int a = 1L;
这不会编译(当然)。 不兼容的类型:从long到int的可能有损转换
int b = 0;
b += Long.MAX_VALUE;
这确实可以编译!
但为什么允许这样做?
答案 0 :(得分:9)
当您b += Long.MAX_VALUE;
执行复合语句并且编译器在内部强制转换它时。在第一种情况下,编译器直接向你喊叫,因为它是直接声明:)
该行
b += (int)Long.MAX_VALUE;
它的编译器版本相当于
One option for long doubles is that gcc 4.6 and later have a library
called quadmath, which implements the IEEE 754 quadruple precision
(128-bit, 113 bits of mantissa) floating point numbers. The library
works at least on x86 and ia64 platforms. It may be part of your gcc
installation, or you may need to install it separately.
With "Configure -Dusequadmath" you can try enabling its use, but note
the compiler dependency, you may need to also add "-Dcc=...".
At C level the type is called C<__float128> (note, not "long double"),
but Perl source knows it as NV.
当然,从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仅被评估一次。
答案 1 :(得分: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