我正在使用Findbugs扫描第三方源代码(只是为了在集成之前要谨慎),并发现以下警告:

long a = b << 32 | c
  

错误:整数移位32个模式ID:   ICAST_BAD_SHIFT_AMOUNT,键入:BSHIFT,   类别:正确

     

代码执行整数移位   超出范围的恒定量   0..31。这样做的效果是使用整数值的低5位   决定转移多少。这个   可能是不希望的,并且   至少令人困惑。

有人可以解释上面究竟是什么意思吗?

谢谢! (我是Java编程的新手)

有帮助吗?

解决方案

来自 Java语言规范

  

如果左侧操作数的提升类型为int,则只使用右侧操作数的五个最低位作为移位距离。就好像右手操作数受到按位逻辑AND运算符&amp; (&#167; 15.22.1),掩码值为0x1f。因此,实际使用的移动距离始终在0到31的范围内,包括0和31。

因此,如果b是int,则表达式与

相同
long a = b | c;

我非常怀疑是什么意思。应该是

long a = ((long) b << 32) | c;

(如果b已经很长,代码是正确的,并且FindBugs误解了这个错误。)

其他提示

编辑:问题几乎肯定源于'b'是'int'而不是'long'这一事实。

在C中,如果'b'是一个整数而不是一个long而你向左移32位,那么原始值中的所有位都被删除了,所以整个表达式的结果将是相同的作为'c',您将调用未定义的行为,因此任何结果都是允许的。 Java以不同的方式定义 - 正如Rasmus Faber的评论和所选答案中所述 - 并且以可以移位的最大位数为模的超长移位。 [做生意似乎很奇怪;我可能已经安排了一个包含它们的语言的例外。但是,它被明确定义,这比定义的确切更重要。]在表达式被评估时,不会发生64位的强制;它在表达式完成并且赋值发生时发生。

对5位的引用是......有趣的。这意味着如果你向左移动,比如48,或二进制110000,则与向左移动16相同。或者,' x&lt;&lt; n '与' x&lt;&lt; (n%32)'。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top