Java中的Xor Bytes

Ken*_*ent 5 java casting xor

Java不支持字节上的逐位操作.我想像这样xor两个字节:

xoredByte = byte1 ^ byte2;
Run Code Online (Sandbox Code Playgroud)

在java中,这必须完成:

xoredByte = (byte) (byte1 ^ byte2);
Run Code Online (Sandbox Code Playgroud)

编译为:

xoredByte = (byte) ((int)byte1 ^ (int)byte2);
Run Code Online (Sandbox Code Playgroud)

这在所有情况下都有效吗?我的意思是,这些等同的陈述是什么?

如果没有,代码将执行此操作是什么?

rge*_*man 12

是的,这两个陈述都是等同的.一般情况下,当使用二元运算符时^,Java会对两个操作数应用"二进制数字提升",以确保它们至少都是int值. JLS第5.6.2节涵盖了这一点:

当运算符将二进制数字提升应用于一对操作数时,每个操作数必须表示可转换为数字类型的值,以下规则适用,顺序如下:

  • 如果任何操作数是引用类型,则进行拆箱转换(第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)类型转换与否,byte1byte2都将被提升到int操作之前.这也是为什么回归(byte)是必要的.


ajb*_*ajb 5

发生的事情是,当从byteto转换为值时int,在一个字节的8位前面插入24个新位.这些位可以是全0或全1(因为byte是有符号类型).因此,结果^可能有24个零或24个为最高有效位.但是,当结果被抛回时byte,无论它们是什么,这些24位都会被丢弃; 并且由于^是逐位完成的,所以低位8位与^在字节上进行操作时相同 - 高位24位对低位8没有任何影响.