你居然问两个完全不同的问题在这里,所以他们必须单独处理。
1.为什么new StringBuffer(Integer.MAX_VALUE)
会抛出一个OutOfMemoryError
?
构造函数StringBuffer
试图实例化一个数组char
,其大小是您传递的值。所以你隐式地尝试实例化一个大小为Integer.MAX_VALUE
的数组。有两个原因可能导致实例化数组。
第一个原因是,你真的没有足够的堆空间。不知道你的程序中还有什么事情发生,或者你的堆设置是什么,我不可能知道这是否会发生在你身上。但是,启动它时,您可以为您的JVM选择最大堆大小,使用-Xmx
选项。显然,假设你的计算机有足够的内存,你需要将它设置为几千兆字节才能使其正常工作(例如-Xmx8g
)。
在实例化数组时,OutOfMemoryError
的第二个原因是您已经超出了最大数组大小。这绝对是在这里发生的。最大数组大小不是由Java语言规范定义的,并且它从JVM到JVM都不相同。在大多数现代JVM中,最大阵列大小为Integer.MAX_VALUE - 2
,但有JVM最大为Integer.MAX_VALUE - 5
或Integer.MAX_VALUE - 8
。无论如何,Integer.MAX_VALUE
确实已超出限制。
2.为什么new StringBuffer(Integer.MAX_VALUE + 16)
会抛出NegativeArraySizeException
?
这是关于Java中的整数运算。任何int
值必须介于Integer.MIN_VALUE
和Integer.MAX_VALUE
之间。此外,当您添加两个int
值时,答案由Java语言规范保证为3210 Integer.MAX_VALUE + 16`,您不会得到数学上正确的答案。实际上,Java所做的就是运行mod 2 。查看它的另一种方法是JVM将添加或减去2的倍数以使答案在正确的范围内。
这意味着Integer.MAX_VALUE + 16
的值实际上在数值上等于,这是一个很大的负数。正如我前面提到的,StringBuffer
构造函数试图实例化一个数组,其大小是您传递的值。这种尝试实例化负数大小的数组会给您带来NegativeArraySizeException
。
诠释溢出... – user2717954
阅读了有关整数溢出 – QBrute
1:*** Integer.MAX_VALUE的+ 16 ***的是,产生负数→无效参数 –