事情的起源还要归结于探索AbstractCollection这个抽象类,因为我在深入的了解集合的一些底层实现,在实现集合转换数组的过程中看到一些方法:
public Object[] toArray()
{
Object aobj[] = new Object[size()];
Iterator iterator1 = iterator();
for(int i = 0; i < aobj.length; i++)
{
if(!iterator1.hasNext())
return Arrays.copyOf(aobj, i);
aobj[i] = iterator1.next();
}
return iterator1.hasNext() ? finishToArray(aobj, iterator1) : aobj;
}
private static Object[] finishToArray(Object aobj[], Iterator iterator1)
{
int i = aobj.length;
for(; iterator1.hasNext(); aobj[i++] = iterator1.next())
{
int j = aobj.length;
if(i != j)
continue;
int k = j + (j >> 1) + 1;
if(k - 2147483639 > 0)
k = hugeCapacity(j + 1);
aobj = Arrays.copyOf(aobj, k);
}
return i != aobj.length ? Arrays.copyOf(aobj, i) : aobj;
}
private static int hugeCapacity(int i)
{
if(i < 0)
throw new OutOfMemoryError("Required array size too large");
else
return i <= 2147483639 ? 2147483639 : 2147483647;
}
先不管方法为了实现什么,看一下第三个方法hugeCapacity()。
看最后那三个数字:2147483639 2147483639 2147483647
总感觉好像似曾相识。
后来知道了最后一个是int取值的最大值,int取值范围 -2147483648-2147483648
然后我就想我们平时定义数组的时候最大能定义多长呢?
我们知道数组里面长度定义使用Int类型,因此最开始我猜测最大为2147483647,结果:
int max1 = 2147483647;
String[] str = new String[max1];
在eclipse中写完是没有红线的,就是说编译没错。运行时
Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit
at collectionDemo.arraylist.Main.main(Main.java:10)
这英文含义大概就是说数组的长度超出虚拟机的限制了。
我第一次运行程序发现错误,就是无法使用异常捕获的这种,所以觉得有时真的需要深入一下
这个问题解决方案或许可以通过修改虚拟机分配的内存大小来解决,但是目前我还没达到这个地步,这就引发我学习虚拟机JVM,也买了一本关于这个方面的书。因此数组能初始化最大的范围应该是2147483647(如果分配内存足够)。
有的人问了,无限大的内存是不是就可以分配无限大的数组,我认为不行,因为前面说过了,int的取值范围最大就是这个了,因此我也试着写了一下:
String[] str = new String[2147483648];
编译时就出错了
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The literal 2147483648 of type int is out of range
说到这,那么和数组紧密相连的集合最大可以放入多少元素呢?
int max = Integer.MAX_VALUE;
List list = new ArrayList();
for (int i = 0; i < max; i++) {
System.out.println(i);
list.add(i);
}
电脑最后跑的同样出错了:我的添加进去7000多万个
70091069
70091070
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.util.Arrays.copyOf(Unknown Source)
at java.util.ArrayList.grow(Unknown Source)
at java.util.ArrayList.ensureExplicitCapacity(Unknown Source)
at java.util.ArrayList.ensureCapacityInternal(Unknown Source)
at java.util.ArrayList.add(Unknown Source)
at collectionDemo.arraylist.Main.main(Main.java:12)
总结:
1、数组最大定义长度和虚拟机定义参数有关,理想情况下最大定义长度2147483647
2、集合也不是无限扩展的哦
3、好好学习JVM吧,这样调试方便