数组's长度属性定义在哪里?

我们可以使用ArrayList<E>的公共方法size()来确定它的长度,比如

ArrayList<Integer> arr = new ArrayList(10);
int size = arr.size();

类似地,我们可以使用length属性确定Array对象的长度

String[] str = new String[10];
int size =  str.length;

虽然ArrayListsize()方法在ArrayList类中定义,但Arraylength属性在哪里定义?

748795 次浏览

数组是java中的特殊对象,它们有一个名为length的简单属性,即final

数组没有“类定义”(你在任何.class文件中都找不到它),它们是语言本身的一部分。

10.7. 数组成员

数组类型的成员都是以下类型:

  • public final字段length,它包含数组的组件数量。length可以为正或零。
  • public方法clone,它覆盖了类Object中同名的方法,并且没有抛出检查异常。数组类型T[]clone方法的返回类型是T[]

    多维数组的克隆是浅的,也就是说它只创建一个新数组。子数组是共享的

  • 所有继承自类Object的成员;Object唯一没有继承的方法是它的clone方法。

资源:

它在Java语言规范中定义:

数组类型的成员都是以下类型:

  • public final字段length,包含数组的组件数。length可以为正或零。

由于数组类型的数量是无限的(每个类都有一个对应的数组类型,并且然后有多维数组),它们不能在类文件中实现;JVM必须在运行中完成它。

它基本上是“特殊的”,有自己的字节码指令:arraylength。这个方法:

public static void main(String[] args) {
int x = args.length;
}

编译成字节码,如下所示:

public static void main(java.lang.String[]);
Code:
0:   aload_0
1:   arraylength
2:   istore_1
3:   return

所以它不像普通字段那样被访问。事实上,如果你试图把它当作一个正常的字段,就像这样,它会失败:

// Fails...
Field field = args.getClass().getField("length");
System.out.println(field.get(args));

所以不幸的是,JLS对每个数组类型的描述都有一个公共final字段length,这有点误导人:(

它的公共final字段,包含数组的组件数量(长度可以为正或零)

因此,数组具有与以下类相同的公共字段和方法:

class A implements Cloneable, java.io.Serializable {
public final int length = X;
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
throw new InternalError(e.getMessage());
}
}
}

更多资料请浏览

10.7数组成员

http://java.sun.com/docs/books/jls/second_edition/html/arrays.doc.html

虽然这不是对问题的直接回答,但它是对.length vs .size()参数的补充。我正在研究与这个问题相关的东西,所以当我遇到它时,我注意到这里提供的定义

公共final字段长度,它包含数组的分量数.;

并不“完全”正确。

字段长度包含放置组件的可用的地方< em > < / em >的数量,而不是数组中存在的组件的数量。所以它表示分配给数组的总可用内存,而不是内存被填满了多少。

Array Memory Allocation

例子:

static class StuffClass {
int stuff;
StuffClass(int stuff) {
this.stuff = stuff;
}
}


public static void main(String[] args) {


int[] test = new int[5];
test[0] = 2;
test[1] = 33;
System.out.println("Length of int[]:\t" + test.length);


String[] test2 = new String[5];
test2[0] = "2";
test2[1] = "33";
System.out.println("Length of String[]:\t" + test2.length);


StuffClass[] test3 = new StuffClass[5];
test3[0] = new StuffClass(2);
test3[1] = new StuffClass(33);
System.out.println("Length of StuffClass[]:\t" + test3.length);
}

输出:

Length of int[]:        5
Length of String[]:     5
Length of StuffClass[]: 5

然而,ArrayList.size()属性确实给出了列表中元素的数量:

ArrayList<Integer> intsList = new ArrayList<Integer>();
System.out.println("List size:\t" + intsList.size());
intsList.add(2);
System.out.println("List size:\t" + intsList.size());
intsList.add(33);
System.out.println("List size:\t" + intsList.size());

输出:

List size:  0
List size:  1
List size:  2

关键字长度就像定义的数据字段。在数组中使用时,可以使用它来访问数组中有多少元素。对于String[],我们可以调用String类中定义的length()方法。对于ArrayList,我们可以使用ArrayList中定义的size()方法。请注意,当使用ArrayList<>(capacity)创建数组列表时,该数组列表的初始size()为零,因为没有元素。

要如实回答它,数组的length属性定义在哪里?在一个特殊的Object header

通过约尔很容易看到

 int [] ints = new int[23];
System.out.println(ClassLayout.parseInstance(ints).toPrintable());

输出的其中一行将是:

OFFSET  SIZE      TYPE DESCRIPTION
16       4        (object header)   17 00 00 00 (00010111 00000000 00000000 00000000) (23)

通常对象有两个头文件(mark和klass),数组有一个头文件,长度总是占用4 bytes,因为sizeint