Java ломает сильную печать! Кто может это объяснить?
Возможный дубликат:
Изменчивое поведение для возможной потери точности
Я обнаружил несогласованность в сильной проверке ввода Java во время компиляции.
Посмотрите на следующий код:
int sum = 0;
sum = 1; //is is OK
sum = 0.56786; //compile error because of precision loss, and strong typing
sum = sum + 2; //it is OK
sum += 2; //it is OK
sum = sum + 0.56787; //compile error again because of automatic conversion into double, and possible precision loss
sum += 0.56787; //this line is does the same thing as the previous line, but it does not give us a compile error, and javac does not complain about precision loss etc.
Может ли кто-нибудь объяснить это мне? Это известная ошибка или желаемое поведение?
С++ дает предупреждение, С# дает ошибку компиляции.
Разрывает ли Java сильную типизацию?
Вы можете заменить + = на - = или * = - все допустимо компилятором.
Ответы
Ответ 1
Это поведение определяется языком (и поэтому хорошо). Из JLS:
15.26.2 Операторы присваивания соединений
Выражение составного присваивания формы E1 op = E2 эквивалентно к E1 = (T) ((E1) op (E2)), где T - тип E1, за исключением того, что E1 оценивается только один раз. Например, следующий код верен:
short x = 3;
x += 4.6;
и приводит к тому, что x имеет значение 7, потому что оно эквивалентно:
short x = 3;
x = (short)(x + 4.6);
Ответ 2
Он компилируется, потому что компилятор преобразует
sum += 0.56787;
к
sum = (int)(sum + 0.56787);
Ответ 3
Это не имеет ничего общего с сильной типизацией, но только с разными правилами для неявных преобразований.
Здесь вы смотрите на два разных оператора. В первом случае у вас есть простой оператор присваивания "=", который не позволяет присваивать double
int
. Во втором случае у вас есть составной оператор присваивания "+ =", который позволяет добавить double
в int
, сначала преобразуя double
в int
.