嗯。考虑一下这个程序,它的目标是找出获得整数的最后16位的最佳方法,作为有符号整数。
public class SignExtend16 {
public static int get16Bits(int x)
{
return (x & 0xffff) - ((x & 0x8000) << 1);
}
public static int get16Bits0(int x)
{
return (int)(short)(x);
}
public static void main(String[] args)
{
for (String s : args)
{
int x = Integer.parseInt(s);
System.out.printf("%08x => %08x, %08x\n",
x, get16Bits0(x), get16Bits(x));
}
}
}
我打算在get16Bits0中使用代码,但是我在Eclipse的编译器中收到了“从必须强制转换为int”的警告,这让我很怀疑,认为编译器可以优化我的“不必要的演员”。当我使用Eclipse的编译器在我的机器上运行它时,我得到两个函数的相同结果,这些函数的行为与我的预期一致(测试参数:1 1111 11111 33333 66666 99999)。这是否意味着我可以使用get16Bits0? (对未来的代码维护者提出适当的警告)我一直认为JRE和编译器行为在算术上都与机器无关,但这种情况在某种程度上测试了我的信念。
答案 0 :(得分:5)
由于数字转换是隐式友好的,我认为你得到警告的唯一原因是编译器总是在返回时将转换为int,使你的显式转换为多余。
答案 1 :(得分:5)
好吧,首先警告是正确的,因为你总是可以通过算术转换“向上”移动。只有另一种方式需要转换,因为您可能会丢失数据(或浮点数的精度)。
当你从int减少到short时,你必须通过使用强制转换表明它是故意的。但是当你将短值转换回int时没有危险,它会自动发生。
所以,你需要的只是
return (short) x;
答案 2 :(得分:4)
如果你想避免演员表,你可以这样做:
(x << 16) >> 16
此技术也适用于不同数量的位。说底15:
(x <&lt; 17)&gt; 17
更改&gt;&gt;到&gt;&gt;&gt;对于未签名的版本。
答案 3 :(得分:0)
是的,get16Bits0应该可以工作,只需在函数前面添加一个suppressWarning元标记。