【发布时间】:2012-05-03 11:52:26
【问题描述】:
鉴于 byte、short 和 int 是有符号的,为什么 Java 中的 byte 和 short 没有得到通常的 signed two's complement 处理?例如 0xff 对于字节是非法的。
这在here 之前已经讨论过,但我找不到原因。
【问题讨论】:
鉴于 byte、short 和 int 是有符号的,为什么 Java 中的 byte 和 short 没有得到通常的 signed two's complement 处理?例如 0xff 对于字节是非法的。
这在here 之前已经讨论过,但我找不到原因。
【问题讨论】:
如果您查看用于以有符号字节存储-1 的实际内存,那么您将看到它是0xff。然而,在语言本身,而不是二进制表示中,0xff 只是超出了一个字节的范围。 -1 的二进制表示确实会使用二进制补码,但您不会受到该实现细节的影响。
语言设计者只是认为试图将 255 存储在只能包含 -128 到 127 的数据类型中应该被视为错误。
你在 cmets 中问为什么 Java 允许:
int i = 0xffffffff;
文字 0xffffffff 是 int 文字,使用二进制补码进行解释。您不能对字节执行任何类似操作的原因是该语言没有提供语法来指定文字的类型为byte,或者实际上是short。
我不知道为什么决定不提供更多文字类型。我希望它是出于简单的原因而制作的。该语言的目标之一是避免不必要的复杂性。
【讨论】:
你可以写
int i = 0xFFFFFFFF;
但你不会写
byte b = 0xFF;
因为 0xFF 是一个 int 值而不是 byte 所以它等于 255。没有办法定义一个字节或短文字,所以你必须转换它。
顺便说一句,你可以这样做
byte b = 0;
b += 0xFF;
b ^= 0xFF;
甚至
byte b = 30;
b *= 1.75; // b = 52.
【讨论】:
0xFFL 是 long
byte b = 255; 你可以写byte b= -1;
它是合法的,但是你需要将它显式地转换为字节,即 (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...
}
在大多数情况下,最好让编译器告诉您该值超出范围,而不是像那样“修复”它。
【讨论】: