为什么byte的最大值加一,却没有溢出

Why the maximum value of byte plus one, but there is no overflow

class Overflowtest {

  public static void main(String[] args) {

    byte maxValue= Byte.MAX_VALUE;
    System.out.println("maxValue of byte is "+maxValue);
    System.out.println("add 1 to maxValue of byte is "+maxValue+(byte)2);

  }
}

为什么我尝试maxValue+(byte)2时没有发生溢出? 但如果我这样做,(byte)(maxValue+2),就会发生溢出。

在您的示例中,您将 127 添加到一个字符串,然后将 2 添加到一个字符串。

但是当你这样做时:

System.out.println(maxValue+(byte)2);

二元运算return一个整数。

正如其他人在解决括号后所说的那样,您可以打印该值

System.out.println("add 1 to maxValue of byte is "
                + (maxValue + ((byte) 2)));

输出结果为 129。

原因是这里发生的事情是 Integer addition。不是字节赋值。所以你没有看到任何异常。

当您将字节转换值添加到 maxValue 时,它会立即变成整数加法。

要检查您的实际问题,请尝试做

byte maxValue2 =(maxValue + ((byte) 2));

这将无法编译,因为结果是一个 int。因此,当您将代码更改为

int  maxValue2 = maxValue + ((byte) 2);

行得通。

当你在将结果转换为字节的帮助下进行字节赋值时,现在再次回到你的旧解释

byte maxValue2 = (byte) (maxValue + ((byte) 2));

现在您可以静静地看到溢出并截断整数的高阶位,并将 maxValue2 的结果截断为 -127

第一个问题是您先将 127 连接到字符串,然后再连接 2。因此您看到的值实际上是“1272”。

但是当您将 (maxValue + (byte)2) 放在括号中时,您会遇到另一个问题:+ 运算符导致 二进制数字提升 。这在Java Language Specification, item 5.6.2:

中提到

When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order:

  1. If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).

  2. Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:

    • If either operand is of type double, the other is converted to double.

    • Otherwise, if either operand is of type float, the other is converted to float.

    • Otherwise, if either operand is of type long, the other is converted to long.

    • Otherwise, both operands are converted to type int.

后面是导致这种二进制数字提升的运算符列表,它包括运算符 +

所以你看,两个操作数都转换为int。并变成 127 + 2,不会溢出 int 范围。结果是 int.

要查看实际溢出,您可能需要执行以下操作:

byte newValue = (byte) (maxValue + (byte)2); // Notice that you can't assign it without the cast!
System.out.println(newValue);

这个溢出实际上并不是加 2 的结果,而是截​​断整数 129 并只取其最右边的字节的结果。