оператор "+ = " и int long usage [дубликат]
На этот вопрос уже есть ответ здесь:
int a = 1L;
Это не компилируется (конечно). несовместимые типы: возможно преобразование с потерями из long в int
int b = 0;
b += Long.MAX_VALUE;
Это действительно компилируется!
Но почему это разрешено?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