4

我们都知道在 Java 中这些操作符:

a++;
++a;
a += 1;
a = a + 1;

做同样的事情,他们只是将 1 加到变量 'a'

然而为什么这些说法并不全是真的,这背后的原理是什么?

byte a = 1;
a++;
++a;
a += 1;
a = a + 1; // This line will result to a compile time error

为什么?

4

2 回答 2

3

每当您在不同类型的两个操作数之间执行二元运算时,其中一个操作数将提升为更高类型。然后操作的结果就是那个类型。

因此,在您的情况下,该byte类型a首先被提升为 an int,因为1它是一种int类型。然后经过加法运算,结果为int. 现在,由于您无法将 a 分配int给 a byte,因此您需要进行类型转换以消除编译器错误:

byte a = 2;
a = a + 1;   // Error: Cannot assign an int value to byte
a = (byte)(a + 1);  // OK


现在,在复合赋值运算符的情况下,类型转换是为您隐式完成的。表达方式:

a += 1

在内部转换为:

a = (byte)(a + 1);

这在 JLS - §15.26.2 复合赋值运算符中指定:

E1 op= E2 形式的复合赋值表达式等价于 E1 = (T) ((E1) op (E2)),其中 T 是 E1 的类型,除了 E1 只计算一次。

前缀增量运算符后缀增量运算符的情况类似。
根据 JLS - §15.15 一元运算符

前缀增量表达式的类型是变量的类型。

于 2013-07-12T05:37:08.953 回答
0

一 = 一 + 1;

这是由于表达式的类型a = a + 1;。LHS 被提升到int然后执行加法。然后,您尝试将int值分配回 abyte而不进行强制转换。

参考JLS 5.6.2

加宽原语转换(第 5.1.2 节)适用于转换以下规则指定的一个或两个操作数:

  1. 如果任一操作数是 double 类型,则另一个操作数将转换为 double。

  2. 否则,如果任一操作数的类型为浮点型,则另一个将转换为浮点型。

  3. 否则,如果任一操作数是 long 类型,则另一个将转换为 long。

  4. 否则,两个操作数都转换为 int 类型。

一个++;++一个;

这里的类型是变量的类型。再次按照JLS 15.15

前缀增量表达式的类型是变量的类型。

前缀减量表达式的类型是变量的类型。

一个+= 1;

根据JLS 15.26.2

E1 op= E2 形式的复合赋值表达式等价于 E1 = (T) ((E1) op (E2)),其中 T 是 E1 的类型,除了 E1 只计算一次。

因此这里a += 1;等同于a = (byte)(a+1);,因为它是隐式完成的。

于 2013-07-12T05:28:38.043 回答