当执行new HashMap<>(10)时都执行了什么?
首先是虚拟机规范有规定,当使用new语句新建对象时会触发类的初始化操作,但那是对于未初始化的类.实际会先去常量池中定位到HashMap类的符号引用,并检查这个类是否已经被加载解析初始化过.没有的话先进行类加载过程.然后为对象分配内存.但是我们从执行构造器开始:
new HashMap<>(10)使用的是一个int参数的构造器:
public HashMap(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
public HashMap(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " +
initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor);
this.loadFactor = loadFactor;
this.threshold = tableSizeFor(initialCapacity);
}
可以看到构造器中只定义了容量和装填因子大小,和一个threshold,这个threshold是什么,我们来看一下:
/**
* The next size value at which to resize (capacity * load factor).
int threshold;
官方的注释中解释是下一次执行resize()的阈值,也就是容量大于它时要进行resize扩容操作.但是有一种特殊情况,就是在第一次执行resize操作的时候,threshold是建立数组的大小.下面会有介绍到.
下面我们看到threshold是用这句this.threshold = tableSizeFor(initialCapacity);
来给初始值的. 那tableSizeFor做了什么:
/**
* Returns a power of two size for the given target capacity.
*/
static final int tableSizeFor(int cap) {
int n = cap - 1;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}
直接看可能有点蒙,看官方给出的解释,也就是顶上的注释行: 返回一个比给定值大的最小的二的次幂. 我们这里传进来的是10,那么最后return 的是什么:
n-1后变成 9
n |= n >>> 1后n=13
n |= n >>> 2后n=15
n |= n >>> 4后n=15
n |= n >>> 8后n=15
n |=