当字节超过大小限制时为什么没有溢出?

5
在Java中,当不断递增一个Byte值时,如果超过了大小容量,为什么不会抛出任何运行时异常?例如:
public static void main(String[] args) {
    byte b = 127;
    ++b;
    System.out.println(b);
}

上面的代码将打印-128。如果它抛出RuntimeException,那不是更好吗?为什么要设计成这样?
对于其他基本类型也是一样,例如Integer:
int c = 2147483647;
++c;
System.out.println(c);

上面的代码打印出 -2147483648
3个回答

7
整数溢出在计算中实际上非常有用。如果它引发异常,许多聪明的算法将突然变得不可行或无法实现。例如,任何涉及定点算术的事情都会突然充满异常。
问题在于,溢出通常不是问题,因为我们在程序中设置限制,以防止其发生(如果它会导致问题)。其他时候,我们设计程序专门利用它。
不要认为溢出是“值超过其最大大小”。这在技术上是不可能的。比特只是环绕并保持在该数据类型的限制范围内。
如果您需要检查溢出并想生成异常,则可以执行以下操作:
byte b = 127;
byte oldb = b;
b++;
if( b < oldb ) {
    // Calamity!!!  Raise an exception!
}

不要害怕整数限制。学会理解和处理它们。


1

JVM规范中指出:“尽管可能会发生溢出,但执行iadd指令永远不会抛出运行时异常。”


1
整数和浮点算术的工作方式基于C语言中相同操作的工作方式,而C语言的工作方式又基于CPU通常的工作方式。溢出或下溢不会触发异常(除了一些标志,不幸的是Java无法访问)。只有一种操作会触发异常,那就是整数除以零,这会在许多类型的CPU上触发处理器中断。浮点除以零被定义为非数字,因此不会触发中断。

在一个32位的计算机中,为了进行64位的运算,编译器必须有智能来组合两个32位(2字节)。在这种情况下,它不需要知道溢出发生的知识吗? - Karthik
一个32位处理器具有加减乘比较操作,可以组合成任意长度的位。除法更为复杂,但可以用循环完成。 - Peter Lawrey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接