К моему шоку, оказалось, что следующий код компилируется даже без предупреждений:
public void test()
{
int value = 2000000000;
long increment = 1000000000;
value += increment;
}
В то время как это дает ошибку времени компиляции, как и следовало ожидать:
public void test()
{
int value = 2000000000;
long increment = 1000000000;
value = value + increment;
}
Я проверил это, и действительно , JLS (раздел 15.26.2) сообщает следующее:
Составное выражение присваивания в форме E1 op = E2 эквивалентно E1 = (T) ((E1) op (E2)), где T - тип E1, за исключением того, что E1 вычисляется только один раз.
Мне это кажется смешным. Почему они посчитали необходимым использовать здесь явное приведение? Кажется, что автоматическое преобразование типов в любом случае обработало бы расширение, а автоматическое сужение, подобное этому, почти гарантированно приведет к целочисленному переполнению.