考虑:
long n = Long.MAX_VALUE;
++n;
使用我的JVM,这将绕回Long.MIN_VALUE
。这是定义的行为吗?一些JVM会抛出异常吗?
答案 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
。