欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

通过反射查看ArrayList的空参构造初始容量浅析

程序员文章站 2022-06-27 20:31:26
今天在看ArrayList的源码时发现,ArrayList的空参构造方法中默认初始容量是0,有一点感到不解,上课老师有提到过ArrayList的初始容量是10。找来旧版查看JDK源码后发现,JDK1.6、1.7、1.8在ArrayList的空参构造方法上有略微区别。 看JDK1.8的源码: private static final int DEFAULT_CAPACITY = 10; private static final Object[] DEFAULTC......


今天在看ArrayList的源码时发现,ArrayList的空参构造方法中默认初始容量是0,有一点感到不解,上课老师有提到过ArrayList的初始容量是10。找来旧版查看JDK源码后发现,JDK1.6、1.7、1.8在ArrayList的空参构造方法上有略微区别。
看JDK1.8的源码:

 private static final int DEFAULT_CAPACITY = 10;
     private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
      /**
     * Shared empty array instance used for empty instances.
     */
     private static final Object[] EMPTY_ELEMENTDATA = {};
   /**
     * Constructs an empty list with an initial capacity of ten.
   */
     public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

JDK1.7的源码

public ArrayList() {
        super();
        this.elementData = EMPTY_ELEMENTDATA;
    } 

JDK1.6的源码

 /**
     * Constructs an empty list with an initial capacity of ten.
     */
   public ArrayList() {
   this(10);
   }

可以看出1.6的源码直接在构造方法中默认初始容量为10.而1.7、1.8在构造方法中默认初始容量为空,

1.8源码涉及到扩容的代码

/**
     * Increases the capacity of this <tt>ArrayList</tt> instance, if
     * necessary, to ensure that it can hold at least the number of elements
     * specified by the minimum capacity argument.
     *
     * @param   minCapacity   the desired minimum capacity
     */
    public void ensureCapacity(int minCapacity) {
        int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
            // any size if not default element table
            ? 0
            // larger than default for default empty table. It's already
            // supposed to be at default size.
            : DEFAULT_CAPACITY;

        if (minCapacity > minExpand) {
            ensureExplicitCapacity(minCapacity);
        }
    } 


从这一段代码我们已经可以看出,ArrayList的底层实现是数组,原来第一次在ArrayList集合中添加元素时,会把数组初始化为10。这一点我们可以利用反射原理来验证,通过暴力反射强行获取elementData数组的长度,也就是ArrayList的容量Capacity

public class Demo1 {
	public static void main(String[] args) throws Exception {
		ArrayList list=new ArrayList();
		Class clazz=Class.forName("java.util.ArrayList");
		Field elementData=clazz.getDeclaredField("elementData");
		elementData.setAccessible(true);
		Object[] arr=(Object[]) elementData.get(list);
		System.out.println(arr.length);
	}
}

运行结果为:


通过反射查看ArrayList的空参构造初始容量浅析

可以看出ArrayList的初始容量确实为0。

在往集合中添加两个元素后会发现

public class Demo1 {
	public static void main(String[] args) throws Exception {
		ArrayList list=new ArrayList();
		list.add("a"); 
		list.add(1);
		Class clazz=Class.forName("java.util.ArrayList");
		Field elementData=clazz.getDeclaredField("elementData");
		elementData.setAccessible(true);
		Object[] arr=(Object[]) elementData.get(list);
		System.out.println(arr.length);
	}
} 

运行结果:

通过反射查看ArrayList的空参构造初始容量浅析




此时集合中容量已经为10。

本文地址:https://blog.csdn.net/m0_37777530/article/details/108027668

相关标签: java jdk