【问题标题】:"+=" operator and int long usage [duplicate]“+=”运算符和int long用法[重复]
【发布时间】:2015-12-18 03:27:30
【问题描述】:
int a = 1L;

这不会编译(当然)。 不兼容的类型:从 long 到 int 的可能有损转换

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

这确实可以编译!

但为什么允许呢?

【问题讨论】:

    标签: java


    【解决方案1】:

    当您执行+= 时,这是一个复合语句,编译器会在内部对其进行强制转换。在第一种情况下,编译器直接对你大喊大叫,因为它是直接声明:)

    线

    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 只计算一次。

    【讨论】:

    • 啊,我自己在规范中没有找到它。那么编译器/IDE的警告会很好。
    【解决方案2】:

    实际上编译器比你想象的要聪明。在编译时,它会将表达式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
    

    【讨论】:

    • hm 目前我认为编译器在这里太“聪明”了
    猜你喜欢
    • 2017-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-11
    • 1970-01-01
    • 2020-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多