为什么Java增量运算符允许在没有显式转换的情况下缩小操作?

可能重复:
Java + =运算符

在Java中,这是无效的(不编译),如预期的那样:

long lng = 0xffffffffffffL; int i; i = 5 + lng; //"error: possible loss of magnitude" 

但这很好(?!)

 long lng = 0xffffffffffffL; int i = 5; i += lng; //compiles just fine 

这显然是一个缩小的操作,可能超过int范围。 那么编译器为什么不抱怨呢?

i += lng; 复合赋值运算符cast隐式。

 i+=lng; is same as i = int(i+lng); 

来自JLS :

formsE1 op = E2的复合赋值表达式等效于E1 =(T)((E1)op(E2)),其中T是E1的类型,除了E1仅被评估一次。

这在JLS#15.26.2中定义:

formsE1 op= E2的复合赋值表达式等效于E1 = (T) ((E1) op (E2)) ,其中TE1的类型,除了E1仅被评估一次。

换句话说, i += lng隐式执行演员表。

根据JLS§15.26.2 ,编译器不会抱怨。 复合赋值运算符 :

formsE1 op= E2的复合赋值表达式等效于E1 = (T) ((E1) op (E2)) ,其中TE1的类型,除了E1仅被评估一次。

从而,

 i += lng; 

相当于

 i = (int)(i + lng);