二进制加法执行类型边界检查,而 shorthand 和增量不执行

Binary addition performs type boundary checking whereas shorthand and increment doesn't

我看到下面的代码:

byte b = 127;
b = b + 1;
b = b + 1;
System.out.println(b);

导致在运行时进行边界检查,第一次添加 b 超出范围,导致以下错误 -

Main.java:11: error: incompatible types: possible lossy conversion from int to byte b=b+1; Main.java:12: error: incompatible types: possible lossy conversion from int to byte b=b+1;

但是,当我使用 shorthand 或增量时,如:

byte b = 127;
b += 1;
b++;
System.out.println(b);

我们发现字节'wraps around'的值,给出输出

-127

为什么会出现这种异常?究竟是什么阻止了加法回绕(像 C 所做的那样),或者 increment/shorthand 进行边界检查?

对于 byte 最小值为 -128 (-2^7) 最大值为 127 因此 if greater converts to int

byte b  = (int) b + 1

因此无法将large int转换为byte

Why this anomaly?

当你添加一个 byte 加上一个 int 你会得到一个 int 所以当你将它分配给一个 byte 它会抱怨。但是当你做

b += 1;

此操作中存在隐式转换,虽然不明显,但在 JLS 中。一个更清楚的例子是

char ch = '0';
ch /= 0.9; // << an implicit cast occurs here.
System.out.println(ch); // 5

同样,当你这样做时

b++;

为了编译,它必须假定可能发生溢出。

简而言之,区别在于

b = b + 1;

有两个运算符而不是一个,这会导致可能发生溢出的警告。

注意:这不适用于 intlong 类型,您可以这样做

int i = Integer.MAX_VALUE;
i = i + 1; // no warning as int is not widened to long
long l = Long.MAX_VALUE;
l = l + 1; // no warning as long is the widest type.

即使 Java 10 可能对 128 位整数有 Long2(并且它可能)long 仍然不会被加宽。