鉴于 byte、short 和 int 是有符号的,为什么 Java 中的 byte 和 short 没有得到通常的有符号二进制补码处理?例如 0xff 对于字节是非法的。
这已经在这里讨论过,但我找不到为什么会这样的原因。
如果您查看用于存储-1
有符号字节的实际内存,那么您会看到它是0xff
. 然而,在语言本身中,而不是二进制表示,0xff
只是超出了一个字节的范围。的二进制表示-1
确实会使用二进制补码,但您不受该实现细节的影响。
语言设计者的立场是,试图将 255 存储在只能保存 -128 到 127 的数据类型中应该被视为错误。
您在评论中询问为什么 Java 允许:
int i = 0xffffffff;
文字0xffffffff
是int
文字,使用二进制补码进行解释。您不能对字节执行任何类似操作的原因是该语言不提供语法来指定字面量是类型byte
,或者确实是类型short
。
我不知道为什么决定不提供更多文字类型。我希望它是出于简单的原因而制作的。该语言的目标之一是避免不必要的复杂性。
你可以写
int i = 0xFFFFFFFF;
但你不能写
byte b = 0xFF;
因为 0xFF 是一个int
值而不是 abyte
所以它等于 255。没有办法定义字节或短文字,所以你必须转换它。
顺便说一句你可以做
byte b = 0;
b += 0xFF;
b ^= 0xFF;
甚至
byte b = 30;
b *= 1.75; // b = 52.
这是合法的,但是您需要将其显式转换为字节,即 (byte)0xff 因为它超出了范围。
您可以从字面上设置一个字节,但令人惊讶的是,您必须使用更多数字:
byte bad = 0xff; // doesn't work
byte b = 0xffffffff; // fine
逻辑是,0xff 隐含为 0x000000ff,超出了一个字节的范围。(255)
这不是你得到的第一个想法,但它有一些逻辑。较长的数字是较小的数字(和较小的绝对值)。
byte b = 0xffffffff; // -1
byte c = 0xffffff81; // -127
byte c = 0xffffff80; // -128
byte
范围从 -128 到 127的可能值。
可以将范围之外的值分配给变量,并默默地丢弃溢出,但这宁愿令人困惑而不是方便。
然后我们会有:
byte b = 128;
if (b < 0) {
// yes, the value magically changed from 128 to -128...
}
在大多数情况下,最好让编译器告诉您该值超出范围,而不是像那样“修复”它。