Страницы

Поиск по вопросам

вторник, 28 января 2020 г.

использование операторов +=, = Java

#java


Почему в строке 1 возникает ошибка компиляции, а в строке 2 нет?

public class text {

  public static void main(String[] args) {
    byte b1 = 127;
    b1 = b1 + 1; // 1
    b1 += 1;     // 2
  }
}

    


Ответы

Ответ 1



Для сложения в JVM есть 4 опкода - iadd, ladd, fadd и dadd. Для типов integer, long, float и double, соответственно. Поэтому сложение двух байт будет скомпилировано в iload_1 iload_2 iadd istore_3 То есть операнды будут загружены в стек как integer'ы и результат сложения вернётся в виде integer. А попытка сохранить integer в byte без явного преобразования может привести к переполнению. О чём предупреждает компилятор. Это поведение зафиксировано в JLS 5.6.2: When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order: If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8). Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules: If either operand is of type double, the other is converted to double. Otherwise, if either operand is of type float, the other is converted to float. Otherwise, if either operand is of type long, the other is converted to long. Otherwise, both operands are converted to type int. Операция b1 += 1; будет скомпилирована в iload_1 iconst_1 iadd i2b istore_1 Интересен здесь опкод i2b - преобразование из integer в byte. То есть компилятор делает неявное приведение типов. А это поведение зафиксировано в JLS 15.26.2: A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T) ((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.

Ответ 2



См. документацию Compound Assignment Operators Здесь вывод 'b1 += 1' интерпретируется в 'b1 = (byte) b1 + 1'

Комментариев нет:

Отправить комментарий