См. http://cplusplus.github.io/LWG/lwg-active.html#2224 .
Доступ к типу библиотеки после запуска деструктора - это неопределенное поведение , Lambdas не являются библиотечными типами, поэтому у них нет такого ограничения. Когда введен деструктор типа библиотеки, инварианты этого типа библиотеки больше не сохраняются. Язык не применяет такое ограничение, поскольку инварианты по большей части являются концепцией библиотеки, а не понятием языка.
Попробуйте этот пример
public class Main
{
public static void main(String[] args) {
Main main = new Main();
System.out.println(main.addInteger(5, 5));
}
public Long addInteger(Integer a, Integer b) {
Integer sum = a + b;
return sum.longValue();
}
}
Вам необходимо привести сумму к long
как:
(int
+ int
) = int
приведение к [117 ]
public Long addIntegers(Integer a, Integer b) {
return (long) (a + b);
}
(int
приведен к long
) + int
=
long
public Long addIntegers(Integer a, Integer b) {
return (long) a + b;
}
[1117 ] Также:
attributs
class Wrapper {
public static void main(String[] args) {
Wrapper aWrapper = new Wrapper();
Long res = aWrapper.addIntegers(2, 5);
}
public Long addIntegers(Integer a, Integer b) {
return (long) a + b;
}
}
Вот самый простой метод:
public Long addIntegers(Integer a, Integer b) {
return (long)a+b;
}
Что происходит?
a
и b
неявно преобразуются в int
в a+b
. Поскольку результат a+b
может быть больше максимального значения int
(int = 32bit, long = 64bits), мы должны явно привести результат к long
. Когда мы возвращаем long
, он неявно преобразуется в Long
из-за типа возвращаемого метода.
blockquote>public Long addIntegers(Integer a, Integer b) { Integer sum = a + b; return sum; }
Вы почти правы в этом. Я понимаю, почему вы думаете, что это сработает, но вы не можете выйти из
Integer -> Long
ни косвенно, ни через приведение. Вам нужно пойтиInteger -> int -> long -> Long
, и Java может сделать только 1 скачок неявно .Сначала давайте посмотрим, что на самом деле делает
a + b
. Он распаковываетa
иb
изInteger
в примитивныеint
с и складывает их вместе, в результате чего получаетсяint
. Затем он автоматически упаковывает это вInteger
, потому что это тип переменнойsum
, которую вы определили.Но, подождите, мы видим выше (
Integer -> int -> long -> Long
), чтоInteger
на самом деле дальше от того места, где мы хотим быть, а не ближе!Итак, давайте вернемся к
a + b
, который возвращаетint
. Мы хотимLong
. Мы могли бы привести результат кlong
:public Long addIntegers(Integer a, Integer b) { return (long) (a + b); }
В таком случае у нас есть
int
- результат нашего выражения суммы - и мы явно приведем кlong
, и Java делает последний неявный шаг и автоматически помещает его вLong
.Однако, хотя приведение в порядке в нашем случае, это часто признак плохого дизайна, поэтому я стараюсь по возможности избегать его использования. К счастью, в нашем случае мы можем избежать броска. Нам просто нужно переключить неявный шаг и явные шаги (т.е. неявно преобразовать из
int -> long
и явно преобразовать изlong -> Long
)public Long addIntegers(Integer a, Integer b) { return Long.valueOf(a + b); }
В этом примере
Long.valueOf
принимает примитивlong
и возвращаетLong
, но наши вычисленияa + b
возвращают int, поэтому Java неявно преобразуетint
вlong
.
Поскольку a
и b
относятся к типу Integer
, следовательно, вы можете вызвать метод longValue
, чтобы получить их как длинные и суммировать их и вернуть значение, которое будет длинным, без необходимости явного приведения. 115]
public static Long addIntegers(Integer a, Integer b) {
return a.longValue() + b.longValue();
}
Заметьте, что поскольку мы добавляем два длинных значения, мы также гарантируем, что он не столкнется с каким-либо риском переполнения целых чисел, поскольку сложение двух больших целых чисел может столкнуться с ним.