Java 字节一元运算
我们都知道,在Java中,这些操作符:Java 字节一元运算,java,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 为什么?a=a+1 这是由于表达式的类型a=a+1。LHS升级为int,然后执行添加。然后,您尝试将int值重新分配给字节,
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
为什么?a=a+1强> 这是由于表达式的类型
a=a+1代码>。LHS升级为int
,然后执行添加。然后,您尝试将int
值重新分配给字节
,而无需强制转换
参考
加宽基元转换(§5.1.2)用于转换以下规则指定的一个或两个操作数:
如果其中一个操作数的类型为double,则另一个操作数将转换为double
否则,如果其中一个操作数的类型为float,则另一个操作数将转换为float
否则,如果其中一个操作数的类型为long,则另一个操作数将转换为long
否则,两个操作数都将转换为int类型
a++;
++a强>
这里的类型是变量的类型。再次按照
前缀增量表达式的类型是变量的类型
前缀减量表达式的类型是变量的类型
a+=1强>
按照
形式为E1 op=E2的复合赋值表达式等价于E1=(T)((E1)op(E2)),其中T是E1的类型,但E1仅计算一次
因此这里a+=1
相当于a=(字节)(a+1)当您在两个不同类型的操作数之间执行二进制运算时,其中一个操作数将升级为更高的类型。然后操作的结果就是这种类型
因此,在您的例子中,byte
typea
首先被提升为int
,因为1
是int
类型。然后在加法运算之后,结果的类型为int
。现在,由于无法将int
分配给字节
,因此需要执行类型转换以删除编译器错误:
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-中有规定:
形式为E1 op=E2的复合赋值表达式等价于E1=(T)((E1)op(E2)),其中T是E1的类型,但E1仅计算一次
前缀增量运算符和后缀增量运算符的情况类似。
根据JLS-:
前缀增量表达式的类型是变量的类型
基于Java教程:赋值、算术和一元运算符,声明这两行x+=1;和x=x+1都是复合赋值side注意:这不仅仅是扩大转换,因为a=a+(byte)1
也不起作用。另外,整数算术运算总是在int
或long
上进行。如果你使用的是较小的字体,你总是必须对结果进行转换。@Joey。是的,任何二进制运算的结果的类型都至少为int
。您的意思是Java算术运算符假定所有操作数都是“int”或“long”类型?@Chalk\u dusT不假定,根据JLS 5.6.2转换为int
或long
。@Chalk\u dusT。不,不是那样的。如果两个操作数的类型都小于int
,则即使如此,它们也将升级为int
。