Java – 用整数和字节进行位移

考虑以下代码(其中byteIndex是一个int):

int bitNumber = b-(8*byteIndex); bitMask = 0x8>>(byte)bitNumber; 

这会产生错误

 error: possible loss of precision 

编译时(必需字节,找到int)。

代码

 int bitNumber = b-(8*byteIndex); bitMask = 0x8>>2; 

编译好。

这里有什么问题,如何修复第一个允许按int值移位的示例?

编辑:在评论之后,这是一个更完整的例子:

 48) int byteIndex; 49) byte bitMask; 50) int bitNumber; // assign value to byteIndex 67) bitNumber = b-(8*byteIndex); 68) bitMask = 0x8>>bitNumber; 

并且给出的错误是:

 ...MyClass.java:68: error: possible loss of precision bitMask = 0x8>>bitNumber; ^ required: byte found: int 1 error 

将您的shifting线转换为: –

 byte bitMask = (byte)(0x8>>(byte)bitNumber); 

你的RHS是一个int,你需要将它强制转换为byte。

上面的代码将工作正常..有或没有将bitNumberbyte

所以,你也可以: –

 byte bitMask = (byte)(0x8>>bitNumber); 

但是,这是一个问题 – byte bitMask = 0x8>>3; 工作得很好..为什么会这样?

这里有一些例子来解释其工作背后的原因以及final的行为: –

 byte bitMask; int varInt1 = 3; final int finalVarInt2 = 3; final int finalVarInt3 = 4; bitMask = 0x8>>varInt1; // 1. Will not work. bitMask = 0x8<<3; // 2. Will work bitMask = 0x8<<4; // 3. Will not work bitMask = 0x8< 

以下是解释上述行为的一些推理: -

  • ,只有当编译器确定它能够在LHS的byte变量中容纳该值时,RHS上的值才会被隐式地进行typecasted 。否则,我们必须做Explicit type casting来告诉编译器,我们知道我们在做什么,只为我们做..

现在让我们逐一考虑所有情况(从上面的代码(1-3,1-2): -

  1. varInt1最初包含3 。 所以RHS的价值评估为64 。 尽管这个值可能适用于LHS中的 byte变量,但编译器也知道,可以更改varInt1的值。那么如果varInt1值在某个阶段更改为4 ,那该怎么varInt1 ...它将无法工作..这就是为什么不允许..
  2. 现在,在这种情况下,因为我们在这里明确使用了Integer Literal ,所以编译器确保它可以容纳在byte 。所以它允许implicit转换..
  3. 同样,在这种情况下,已知RHS将评估为128 ,不能在byte容纳.. 再次失败 ..

最后两种情况与常规变量不同...由于它们被声明为final ,因此无法重新初始化。因此,编译器可以根据指定的值做出决定。

  1. 在这种情况下,编译器会看到, finalVarInt2包含值3 。 因此, RHS评估为64 ,可以容纳在LHSbyte变量中。 现在,由于变量是final ,因此无法更改,并且Compiler知道这一点,因此确保t * 他的值将始终为64 * ..因此编译器允许这样做。

  2. 在最后一种情况下, finalVarInt3值是4 ..类似的推理..不适合LHS ,因为RHS评估为128 ,不能适合byte

在您的第一个示例中,bitnumber是一个int(32位),当您将其转换为字节(8位)时,您将丢失高位24位。 因此你正在失去精确度。 只需关闭演员(字节)即可。

事实上,这不是答案,正确的答案是Rohit Jain所写的,但这是我第一次看到JVM的这种行为,比较这些代码:

bitNumber标记为final的版本

 final int bitNumber = 10; final byte bitMask = 0x8 >> bitNumber; 

bitNumber不是final的版本

 int bitNumber = 10; bitNumber = 10; final byte bitMask = 0x8 >> bitNumber; 

并且有错误是第二个例子,可能是一些优化。 如果有人知道原因会很棒;-)