字节一元操作

时间:2013-07-12 05:13:58

标签: java

我们都知道在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

为什么?

2 个答案:

答案 0 :(得分:3)

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

因此,在您的情况下,byte类型a首先会提升为int,因为1int类型。然后在加法运算之后,结果为int类型。现在,由于您无法将int分配给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 Compound Assignment Operator

  

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

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

  

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

答案 1 :(得分:0)

a = a + 1;

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

参考JLS 5.6.2

  

应用扩展基元转换(第5.1.2节)来转换以下规则指定的一个或两个操作数:

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

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

  4.   
  5. 否则,如果任一操作数的类型为long,则另一个操作数转换为long。

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

  8.   

<强>一个++; ++一个;

这里的类型是变量类型的类型。再次根据JLS 15.15

  

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

     

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

a + = 1;

根据JLS 15.26.2

  

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

因此,a += 1;相当于a = (byte)(a+1);,因为它是隐式完成的。