Java不支持对字节进行逐位操作。我想像这样xor两个字节:
xoredByte = byte1 ^ byte2;
在java中,这必须完成:
xoredByte = (byte) (byte1 ^ byte2);
编译为:
xoredByte = (byte) ((int)byte1 ^ (int)byte2);
这在所有情况下都有效吗?我的意思是,这些等同的陈述是什么?
如果没有,代码将执行此操作是什么?
答案 0 :(得分:12)
是的,这两个陈述都是等同的。在使用二进制运算符(包括^
)时,Java会对两个操作数应用“二进制数字提升”,以确保它们都至少为int
值。 Section 5.6.2 of the JLS涵盖了这一点:
当运算符将二进制数字提升应用于一对操作数时,每个操作数必须表示可转换为数字类型的值,以下规则适用:
如果任何操作数属于引用类型,则进行拆箱转换(第5.1.8节)。
应用扩展基元转换(第5.1.2节)来转换以下规则中指定的一个或两个操作数:
如果任一操作数的类型为double,则另一个操作数转换为double。
否则,如果任一操作数的类型为float,则另一个操作数转换为float。
否则,如果任一操作数的类型为long,则另一个操作数转换为long。
否则,两个操作数都转换为int 。
(强调我的)
和
对某些运算符的操作数执行二进制数字提升:
乘法运算符*,/和%(§15.17)
数字类型的加法和减法运算符+和 - (§15.18.2)
数字比较运算符<,< =,>和> =(§15.20.1)
数字相等运算符==和!=(§15.21.1)
整数位运算符&,^和| (§15.22.1)
在某些情况下,条件运算符? :(§15.25)
(强调我的)
无论您是否应用(int)
演员表,byte1
和byte2
都会在操作前提升为int
。这也是为什么回归(byte)
是必要的。
答案 1 :(得分:5)
当值从byte
转换为int
时,会发生一个字节的8位前面插入24个新位。这些位可以是全0或全1(因为byte
是有符号类型)。因此^
的结果可能有24个零或24个为最高位。但是,当结果被转回byte
时,无论它们是什么,这些24位都会被丢弃;并且由于^
是逐位完成的,所以低位8位与在字节上进行^
操作时相同 - 高位24位对较低的8没有任何影响。