Учитывая, что эта ситуация может очень легко привести к потере данных из-за необходимого сужающего преобразования в какой-то момент во время выполнения оператора (либо оценка выражения r-значения, либо присвоение), почему i + = l;не ошибка времени компиляции или хотя бы предупреждение?
Это, вероятно, должно быть, как вы сказали, либо ошибка времени компиляции, либо хотя бы предупреждение.Большинство книг и учебных пособий, которые мне известны, представляют x += y;
как сокращение для x = x + y;
.Я, честно говоря, не знаю ни одного, которое делает различие, обозначенное в разделе 15.26.2 Составных операторов присваивания JLS, кроме одного.
В главе 2 (загадка 9) из Java Puzzlers: ловушки, ловушки и угловые случаи авторы (Джошуа Блох и Нил Гафтер) просят вас предоставить объявления для x
и i
, чтобы это было юридическое утверждение:
x += i;
и это не так:
x = x + i;
Существует множество решений, включая первые две строки кода, которые вы разместили в своем вопросе.Авторы предостерегают от использования составных операторов присваивания для переменных типов byte
, short
и char
и рекомендуют при использовании этих операторов для переменных типа int
проверять, что выражение RHS не являетсяlong
, float
или double
.
Они завершаются следующим наблюдением (выделено мое):
Таким образом, составные операторы присваивания молча генерируют приведение.Если тип результата вычисления шире, чем у переменной, сгенерированный приведение является опасным сужающим приведением.Такие броски могут молча отказаться от точности или величины. Для разработчиков языков, вероятно, ошибка для составных операторов присваивания создавать невидимые приведения;составные присваивания, в которых переменная имеет более узкий тип, чем результат вычисления, вероятно, должны быть недопустимыми.