Подтвердить что ты не робот

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 сильную типизацию? Вы можете заменить + = на - = или * = - все допустимо компилятором.

4b9b3361

Ответ 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.