将Java递增超过最大值时的行为

时间:2014-02-07 09:41:43

标签: java

考虑:

long n = Long.MAX_VALUE;
++n;

使用我的JVM,这将绕回Long.MIN_VALUE。这是定义的行为吗?一些JVM会抛出异常吗?

4 个答案:

答案 0 :(得分:3)

来自JLS:

  

如果整数加法溢出,则结果是数学和的低阶位,如某些足够大的二进制补码格式所示。如果发生溢出,则结果的符号与两个操作数值的数学和的符号不同。

来源:http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.18.2

答案 1 :(得分:2)

Long.MAX_VALUE 9223372036854775807 = +(2^63-1) : 

01111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111

++ n将递增此二进制数,因此将使用符号位:

Long.MIN_VALUE -9223372036854775808 = -(2^63) : 

10000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000

这不是jvm的行为,这就是二进制数的icrementation的行为。

答案 2 :(得分:1)

预期:整数类型静默溢出和下溢

JLS: Primitive Types and Values引用

  

整数运算符不表示任何溢出或下溢   方式。

因此,当Java中的算术类型被签名时,向Long.MAX_VALUE添加1会导致溢出,并且当Java使用2的补码时它会转到Long.MIN_VALUE

由于JLS引用所有整数运算符(如++)将静默溢出值而不会导致任何异常

答案 3 :(得分:0)

正如JLS中指出的那样:

  

整数运算符不表示任何溢出或下溢   方式。

     

整数运算符可以为以下内容抛出异常(第11节)   原因:

     

如果取消装箱,任何整数运算符都可以抛出NullPointerException   需要转换(第5.1.8节)空引用。

     

整数除运算符/(§15.17.2)和整数余数   如果运算符%(§15.17.3)可以抛出ArithmeticException   右手操作数为零。

     

增量和减量运算符++(§15.14.2,§15.15.1)和 -   (§15.14.3,§15.15.2)如果装箱,可以抛出OutOfMemoryError   转换(第5.1.7节)是必需的,并且没有足够的内存   可用于执行转换。

addition(由Svetelin Zarev指出):

  
    

如果整数加法溢出,则结果为低位     数学和的位用一些足够大的数字表示     二进制补码格式。如果发生溢出,则表示符号     结果与两者的数学和的符号不同     操作数值。

  

我认为可以安全地假设在这种情况下不会抛出任何异常,每次它都会溢出到Long.MIN_VALUE