Для простого добавления следующим образом:
public class TestAddition {
public static void main(String args[]){
Double a = 1.4278175434624698E9;
Double b = 0.0;
int c = 0;
c += a;
c += b;
System.out.println("Sum is " + c);
}
}
Я получаю вывод как Sum is 1427817543
Если я использую Integer вместо int, он аккуратно бросает ошибку, но для этого он не дает ошибку и производит этот вывод. Является ли это ошибкой java?
Вы запутались в преобразовании unboxing?
Из типа
Integer
в типint
От типа
Double
to typedouble
Если
r
является ссылкой типаInteger
, то преобразование unboxing преобразуетr
вr.intValue()
Если
r
является ссылкой типаDouble
, то преобразование unboxing преобразуетr
вr.doubleValue()
И сложные операторы присваивания?
Составляющее выражение присваивания формы
E1 op= E2
эквивалентноE1 = (T) ((E1) op (E2))
, гдеT
- типE1
, за исключением того, чтоE1
оценивается только один раз.
Итак, это
c += a;
становится
c = (int) (c + a);
в этом случае мы имеем сложение и операнды повышены.
Если какой-либо операнд имеет ссылочный тип, он подвергается распаковке преобразования (п. 5.1.8).
Если один из операндов имеет тип
double
, другой преобразуется вdouble
.
Таким образом, a
становится
a.doubleValue();
Все выражение
c = (int) ((double) c + a.doubleValue()
Теперь, это не будет работать, если c
был Integer
, так как выражение будет
c = (Integer) (c + b);
в этом случае c + b
является добавлением и применяются те же правила продвижения, что и раньше.
c = (Integer) ((double) c.intValue() + a.doubleValue());
но результат double
значения добавления не может быть передан в Integer
, поэтому он терпит неудачу. В принципе, не используйте оператор составного назначения с обертками (в штучной упаковке).
Это не ошибка. Вы присваиваете значение int
так, чтобы все после запятой игнорировалось.
1.4278175434624698E9
такой же как:
1427817543.4624698
так становится:
1427817543
когда вы назначаете его int
Integer
вместо int
.
Значение правильное, так как int не может содержать десятичные числа.
Когда вы выполняете c+ = b, b сначала преобразуется в целое число, так как int и double являются конвертируемыми типами. Целое и двойное не являются конвертируемыми, и вы получаете сообщение об ошибке.
Обратите внимание, что вы всегда должны использовать BigDecimal для вычисления десятичных значений в Java, иначе вы можете получить некоторые странные результаты.