为什么0b1111_1111 "int cannot be converted to byte"导致编译器错误,而不是0b111_1111?


byte b = 0b1111_1111;
byte c = 0b111_1111;
byte d = 0b0111_1111;

第一行导致编译错误:不兼容的类型。我也试过0xFF和十进制,一样。谢谢

我认为byte意味着不能大于8位所保持的值。0b1111_1111为8位。

Java中的所有基本整数类型都是有符号的。确切地说,byteshortintlong是有符号大端双补整数。这意味着它们从-2n-1运行到2n-1-1,其中n是字节的位数-8(Java中的Byte.SIZE(,因此范围是-128到127。

您使用的数字始终是一个整数;数字文字总是。然而,该整数实际上是以十六进制表示的值0x000000FF。由于它高于127,因此无法存储。但是,您可以进行显式转换;您的值毕竟由8位组成。

byte b = (byte) 0b1111_1111

之所以有效,是因为它只是忽略了值左侧的24位。现在,如果你打印它,你会得到-1作为值,尽管0b1111_1111表示8位二进制补码形式的1

如果你需要它来表示整数值255,那么你需要执行以下小技巧:

int i = b & 0xFF;

它将实际执行以下操作:

  • 首先,它将使用符号扩展将b转换为值0xFFFFFFFF作为整数,因为所有计算都默认为整数,并且它仍然认为b表示-1
  • 然后,它与值0x000000FF(称为"掩码"(进行逐位"与"运算,当然得到代表255的相同值0x000000FF

如果你认为这是一个麻烦,那么你是对的。Java本应使用无符号字节,但它决定只使用一个有符号的特定整数类型。也许有点过于热情,但与C相比仍然有很大的改进,因为C中有太多的整数格式,并且每种格式在不同的机器上可能有不同的表示方式。

最新更新