为什么“ int i = 2147483647 + 1;”可以,但是“ byte b = 127 + 1;”不可编译?

为什么 int i = 2147483647 + 1;可以,但 byte b = 127 + 1;不可编译?

7678 次浏览

常量的计算结果是 int,因此 2147483647 + 1溢出并给出一个新的 int,它可以赋值给 int,而 127 + 1的计算结果也是 int等于 128,它不可赋值给 byte

文字127表示 int 类型的值。字面上的1也是。这两个数的和是整数128。在第二种情况下,问题是要将这个变量赋给一个 byte 类型的变量。它与表达式的实际值无关。这与 Java 不支持强制(*)有关。您必须添加类型转换

byte b = (byte)(127 + 1);

然后编译。

(*)至少不是字符串到整数、浮点到时间... Java 支持强制,如果它们在某种意义上是非丢失的(Java 称之为“扩展”)。

不,“胁迫”这个词不需要纠正。这是经过精心挑选的,而且是正确的。从最接近的来源到手(Wikipedia) : “在大多数语言中,强制这个词被用来表示 [ em > 隐含的][ em ]转换,无论是在编译期间还是在运行期间。”在计算机科学中,类型转换、类型转换和强制是隐式或显式地将一种数据类型的实体转换为另一种数据类型的 不同方法.

作为@MByD 的证据:

编译以下代码:

byte c = (byte)(127 + 1);

因为尽管表达式 (127 + 1)是 int 且超出了 byte类型的范围,但是结果被强制转换为 byte。这个表达产生 -128

JLS3 # 5.2转换作业

(变量 = 表达式)

此外,如果表达式是 byte、 short、 char 或 int 类型的常数表达式(15.28) :

如果变量的类型是 byte、 short 或 char,并且常量表达式的值可以用变量的类型表示,则可以使用收缩基元转换。


没有这个条款,我们就不能写

byte x = 0;
char c = 0;

But should we be able to do this? I don't think so. There are quite some magic going on in conversion among primitives, one must be very careful. I would go out of my way to write

byte x = (byte)0;