оператор "+ = " и int long usage [дубликат]


На этот вопрос уже есть ответ здесь:

int a = 1L;

Это не компилируется (конечно). несовместимые типы: возможно преобразование с потерями из long в int

int b = 0;
b += Long.MAX_VALUE;

Это действительно компилируется!

Но почему это разрешено?
2 6

2 ответа:

Когда вы делаете +=, это составная инструкция, и компилятор внутренне ее приводит. Где как и в первом случае компилятор прямым путем кричал на вас, т. к. это прямое утверждение:)

Линия

b += Long.MAX_VALUE;

Компиляторная версия его эквивалента

b += (int)Long.MAX_VALUE;

Конечно, будет иметь место преобразование с потерями от преобразования long к int.

Http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.26.2

Сложное назначение выражение вида E1 op= E2 эквивалентно E1 = (T) ((E1) op (E2)), где T-Тип E1, за исключением того, что E1 вычисляется только один раз.

На самом деле компилятор умнее, чем вы думаете. Во время компиляции он заменит фактическое значение выражения b+=Long.MAX_VALUE на -1. Таким образом, Long.MAX_VALUE преобразуется в int и присваивается полю int непосредственно во время компиляции)

Байтовый код:

public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=2, args_size=1
         0: iconst_0
         1: istore_1
         2: iinc          1, -1 // Here
         5: return
      LineNumberTable:
        line 4: 0
        line 5: 2
        line 6: 5
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       6     0  args   [Ljava/lang/String;
            2       4     1     b   I