List<Integer> res = new ArrayList<>();
res.add(1);
add
/**
* 增加指定的元素到ArrayList的最后位置
*
* @param e 要添加的元素
* @return
*/
public boolean add(E e) {
// 确定ArrayList的容量大小---严谨
// 注意:size + 1,保证资源空间不被浪费,
// 按当前情况,保证要存多少个元素,就只分配多少空间资源
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
ensureCapacityInternal
/**
* 私有方法:明确 ArrayList 的容量
* 用于内部优化,保证空间资源不被浪费:尤其在 add() 方法添加时起效
*
* @param minCapacity 指定的最小容量
*/
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
calculateCapacity
private static int calculateCapacity(Object[] elementData, int minCapacity) {
// 若 elementData == {},则取 minCapacity 为 默认容量和参数 minCapacity 之间的最大值
// 注:ensureCapacity() 是提供给用户使用的方法,在 ArrayList 的实现中并没有使用
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
ensureExplicitCapacity
/**
* 私有方法:明确 ArrayList 的容量
* - 用于内部优化,保证空间资源不被浪费:尤其在 add() 方法添加时起效
*
* @param minCapacity 指定的最小容量
*/
private void ensureExplicitCapacity(int minCapacity) {
// 将“修改统计数”+1,该变量主要是用来实现fail-fast机制的
modCount++;
// 防止溢出代码:确保指定的最小容量 > 数组缓冲区当前的长度
// overflow-conscious code
if (minCapacity - elementData.length > 0)
// 分配容量
grow(minCapacity);
}
grow
/**
* 私有方法:扩容,以确保 ArrayList 至少能存储 minCapacity 个元素
* - 扩容计算:newCapacity = oldCapacity + (oldCapacity >> 1); 扩充当前容量的1.5倍
*
* @param minCapacity 指定的最小容量
*/
private void grow(int minCapacity) {
// 防止溢出代码
int oldCapacity = elementData.length;
// 运算符 >> 是带符号右移. 如 oldCapacity = 10,则 newCapacity = 10 + (10 >> 1) = 10 + 5 = 15
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 若 newCapacity 依旧小于 minCapacity
if (newCapacity - minCapacity < 0)
//则直接将 minCapacity 赋值给newCapacity值
newCapacity = minCapacity;
// 若 newCapacity 大于最大存储容量,则进行大容量分配
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity 通常接近 size,所以这是一个胜利:
elementData = Arrays.copyOf(elementData, newCapacity);
}
hugeCapacity
/**
* 私有方法:大容量分配,最大分配 Integer.MAX_VALUE
*
* @param minCapacity
*/
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
//MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
copyOf
/**
* 复制指定的数组,截断或填充空值(如有必要),
* 使副本具有指定的长度。对于在原始数组和副本中都有效的所有索引,
* 这两个数组将包含相同的值。对于在副本中有效但在原始副本中无效的任何索引,
* 副本将包含 <tt>null<tt>。当且仅当指定长度大于原始数组的长度时,
* 此类索引才会存在。结果数组与原始数组的类完全相同。
*
* @param <T> the class of the objects in the array
* @param original the array to be copied
* @param newLength the length of the copy to be returned
* @return a copy of the original array, truncated or padded with nulls
* to obtain the specified length
* @throws NegativeArraySizeException if <tt>newLength</tt> is negative
* @throws NullPointerException if <tt>original</tt> is null
* @since 1.6
*/
@SuppressWarnings("unchecked")
public static <T> T[] copyOf(T[] original, int newLength) {
return (T[]) copyOf(original, newLength, original.getClass());
}
copyOf
/**
* 复制指定的数组,截断或填充空值(如有必要),使副本具有指定的长度。
* 对于在原始数组和副本中都有效的所有索引,这两个数组将包含相同的值。
* 对于在副本中有效但在原始副本中无效的任何索引,副本将包含 <tt>null<tt>。
* 当且仅当指定长度大于原始数组的长度时,此类索引才会存在。
* 结果数组属于 <tt>newType<tt> 类。
*
* @param <U> the class of the objects in the original array
* @param <T> the class of the objects in the returned array
* @param original the array to be copied
* @param newLength the length of the copy to be returned
* @param newType the class of the copy to be returned
* @return a copy of the original array, truncated or padded with nulls
* to obtain the specified length
* @throws NegativeArraySizeException if <tt>newLength</tt> is negative
* @throws NullPointerException if <tt>original</tt> is null
* @throws ArrayStoreException if an element copied from
* <tt>original</tt> is not of a runtime type that can be stored in
* an array of class <tt>newType</tt>
* @since 1.6
*/
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
@SuppressWarnings("unchecked")
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
getComponentType
/**
* 返回表示数组组件类型的 {@code Class}。如果此类不表示数组类,则此方法返回 null。
*
* @return the {@code Class} representing the component type of this
* class if this class is an array
* @see java.lang.reflect.Array
* @since JDK1.1
*/
public native Class<?> getComponentType();
JVM_GetComponentType
JVM_ENTRY(jclass, JVM_GetComponentType(JNIEnv *env, jclass cls))
JVMWrapper("JVM_GetComponentType");
oop mirror = JNIHandles::resolve_non_null(cls);
oop result = Reflection::array_component_type(mirror, CHECK_NULL);
return (jclass) JNIHandles::make_local(env, result);
JVM_END
resolve_non_null
inline oop JNIHandles::resolve_non_null(jobject handle) {
assert(handle != NULL, "JNI handle should not be null");
oop result = resolve_impl<false /* external_guard */ >(handle);
assert(result != NULL, "NULL read from jni handle");
return result;
}
array_component_type
oop Reflection::array_component_type(oop mirror, TRAPS) {
// 是不是特权
if (java_lang_Class::is_primitive(mirror)) {
return NULL;
}
// 返回mirror数据地址
Klass* klass = java_lang_Class::as_Klass(mirror);
// 是不是一个数组
if (!klass->oop_is_array()) {
return NULL;
}
// 是一个数组
// oop _component_mirror; // component type, as a java/lang/Class
// oop component_mirror() const { return _component_mirror; }
oop result = ArrayKlass::cast(klass)->component_mirror();
#ifdef ASSERT
oop result2 = NULL;
// 一维数组
if (ArrayKlass::cast(klass)->dimension() == 1) {
if (klass->oop_is_typeArray()) {
result2 = basic_type_arrayklass_to_mirror(klass, CHECK_NULL);
} else {
result2 = ObjArrayKlass::cast(klass)->element_klass()->java_mirror();
}
} else {
// 多维数组
Klass* lower_dim = ArrayKlass::cast(klass)->lower_dimension(); // 引用第 (n-1) 维数组(如果存在)。
assert(lower_dim->oop_is_array(), "just checking");
result2 = lower_dim->java_mirror();
}
assert(result == result2, "results must be consistent");
#endif //ASSERT
return result;
}
as_Klass
Klass* java_lang_Class::as_Klass(oop java_class) {
//%note memory_2
assert(java_lang_Class::is_instance(java_class), "must be a Class object");
// 返回元数据字段的地址
Klass* k = ((Klass*)java_class->metadata_field(_klass_offset));
assert(k == NULL || k->is_klass(), "type check");
return k;
}
metadata_field
// 返回地址
inline Metadata* oopDesc::metadata_field(int offset) const {
return *metadata_field_addr(offset);
}
cast
// Casting from Klass*
static ArrayKlass* cast(Klass* k) {
assert(k->oop_is_array(), "cast to ArrayKlass");
return (ArrayKlass*) k;
}
basic_type_arrayklass_to_mirror
oop Reflection:: basic_type_arrayklass_to_mirror(Klass* basic_type_arrayklass, TRAPS) {
BasicType type = TypeArrayKlass::cast(basic_type_arrayklass)->element_type();
return Universe::java_mirror(type);
}
newInstance
/**
* 创建具有指定组件类型和长度的新数组。调用此方法相当于创建一个数组,如下所示:
* <blockquote>
* <pre>
* int[] x = {length};
* Array.newInstance(componentType, x);
* </pre>
* </blockquote>
*
* <p>The number of dimensions of the new array must not
* exceed 255.
*
* @param componentType the {@code Class} object representing the
* component type of the new array
* @param length the length of the new array
* @return the new array
* @exception NullPointerException if the specified
* {@code componentType} parameter is null
* @exception IllegalArgumentException if componentType is {@link
* Void#TYPE} or if the number of dimensions of the requested array
* instance exceed 255.
* @exception NegativeArraySizeException if the specified {@code length}
* is negative
*/
public static Object newInstance(Class<?> componentType, int length)
throws NegativeArraySizeException {
return newArray(componentType, length);
}
newArray
private static native Object newArray(Class<?> componentType, int length)
throws NegativeArraySizeException;
Java_java_lang_reflect_Array_newArray
JNIEXPORT jobject JNICALL
Java_java_lang_reflect_Array_newArray(JNIEnv *env, jclass ignore,
jclass eltClass, jint length)
{
return JVM_NewArray(env, eltClass, length);
}
JVM_NewArray
JVM_ENTRY(jobject, JVM_NewArray(JNIEnv *env, jclass eltClass, jint length))
JVMWrapper("JVM_NewArray");
JvmtiVMObjectAllocEventCollector oam;
// 将eltClass地址转为oop
oop element_mirror = JNIHandles::resolve(eltClass);
// 反射创建新数组
oop result = Reflection::reflect_new_array(element_mirror, length, CHECK_NULL);
return JNIHandles::make_local(env, result);
JVM_END
arrayOop Reflection::reflect_new_array(oop element_mirror, jint length, TRAPS) {
if (element_mirror == NULL) {
THROW_0(vmSymbols::java_lang_NullPointerException());
}
if (length < 0) {
THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
}
if (java_lang_Class::is_primitive(element_mirror)) {
Klass* tak = basic_type_mirror_to_arrayklass(element_mirror, CHECK_NULL);
return TypeArrayKlass::cast(tak)->allocate(length, THREAD);
} else {
Klass* k = java_lang_Class::as_Klass(element_mirror);
if (k->oop_is_array() && ArrayKlass::cast(k)->dimension() >= MAX_DIM) {
THROW_0(vmSymbols::java_lang_IllegalArgumentException());
}
return oopFactory::new_objArray(k, length, THREAD);
}
}
new_objArray
objArrayOop oopFactory::new_objArray(Klass* klass, int length, TRAPS) {
assert(klass->is_klass(), "must be instance class");
if (klass->oop_is_array()) {
return ((ArrayKlass*)klass)->allocate_arrayArray(1, length, THREAD);
} else {
assert (klass->oop_is_instance(), "new object array with klass not an InstanceKlass");
return ((InstanceKlass*)klass)->allocate_objArray(1, length, THREAD);
}
}
allocate_arrayArray
objArrayOop ArrayKlass::allocate_arrayArray(int n, int length, TRAPS) {
if (length < 0) {
THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
}
if (length > arrayOopDesc::max_array_length(T_ARRAY)) {
report_java_out_of_memory("Requested array size exceeds VM limit");
JvmtiExport::post_array_size_exhausted();
THROW_OOP_0(Universe::out_of_memory_error_array_size());
}
int size = objArrayOopDesc::object_size(length);
Klass* k = array_klass(n+dimension(), CHECK_0);
ArrayKlass* ak = ArrayKlass::cast(k);
objArrayOop o =
(objArrayOop)CollectedHeap::array_allocate(ak, size, length, CHECK_0);
// initialization to NULL not necessary, area already cleared
return o;
}