"+="运算符和int long用法

7
int a = 1L;

这段代码编译不通过(当然了)。 类型不匹配:从 long 到 int 可能会导致数据丢失。

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

这段代码是可以编译通过的!

但是为什么会被允许呢?

2个回答

10
当你使用+=时,这是一个复合语句,编译器在内部进行类型转换。而在第一种情况下,编译器直接报错,因为它是一个直接语句:)
该行
b += Long.MAX_VALUE;

编译器版本是相当于 IT 技术的等效物。
b += (int)Long.MAX_VALUE;

当将long类型转换为int类型时,会存在有损转换的情况。Java中的复合赋值表达式E1 op= E2等价于E1 = (T) ((E1) op (E2)),其中T为E1的类型,但E1只会被计算一次。详见http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.26.2

啊,我明白了。我自己在规格文件中没有找到它。编译器/IDE的警告会很好。 - coder

2

实际上,编译器比你想象的更聪明。在编译时,它将用 -1 替换表达式 b+=Long.MAX_VALUE 的实际值。因此,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

目前我认为编译器在这里太“聪明”了。 - coder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接