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

NIN*_*OOP 261 java arrays

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

ArrayList<Integer> arr = new ArrayList(10);
int size = arr.size();
Run Code Online (Sandbox Code Playgroud)

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

String[] str = new String[10];
int size =  str.length;
Run Code Online (Sandbox Code Playgroud)

虽然size()方法ArrayList是在ArrayList类中定义的,但是这个length属性是在哪里Array定义的?

Col*_*ert 248

数组是在Java中的特殊对象,他们有一个名为一个简单的属性lengthfinal.

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

10.7.数组成员

数组类型的成员是以下所有成员:

  • public final字段length,包含数组的组件数.length可能是正数或零.
  • public方法clone在类中重写相同名称的方法,Object并且不会抛出任何已检查的异常.clone数组类型方法的返回类型T[]T[].

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

  • 所有成员都继承自班级Object; 唯一Object没有继承的clone方法是它的方法.

资源:

  • 另请注意,`ArrayList.size()`提供实际存储在数组中的对象的数量,而`myArray.length`(`[]`)提供"容量".也就是说,如果对于`myArray = new int [10];`,它返回10.它不是你放入数组的对象数. (83认同)
  • @VikasVerma为什么数组不像对象?因为历史.设计Java时,大多数语言创新尝试在语法和风格上与C不相似时都失败了.因此,C++,Objective-C和Java是在那个时代逃避默默无闻的少数语言之一.Java被有意识地设计为包括花括号,[原语](http://en.wikipedia.org/wiki/Primitive_data_type)和普通数组,这些数组对于当时的主流程序员来说似乎很熟悉.查看对James Gosling和其他Sun人的采访.有些人坚持使用Collections进行纯OOP,并避免使用普通数组. (5认同)

Jon*_*eet 114

它基本上是"特殊的",带有自己的字节码指令:arraylength.所以这个方法:

public static void main(String[] args) {
    int x = args.length;
}
Run Code Online (Sandbox Code Playgroud)

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

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

因此,它不像正常字段那样被访问.实际上,如果你试图让它好像是一个普通的字段,就像这样,它会失败:

// Fails...
Field field = args.getClass().getField("length");
System.out.println(field.get(args));
Run Code Online (Sandbox Code Playgroud)

不幸的是,每个具有公共最终字段的数组类型的JLS描述length都有些误导:(

  • 我不记得阿尔伯特·爱因斯坦的名言,但它所说的是“人们非常了解一件事只能以非常简单的方式解释事物”,我认为它非常适合您:) (2认同)
  • @VikasVerma:想想数组对象的大小.所有其他类型都具有固定大小 - 每个实例的大小相同,而数组则根据其长度而变化.这只是一个例子.如果你认为你可以在不使用任何特殊内容的情况下获得相同的结果,你认为数组类的字段是什么样的?当泛型不适用于原始类型时,你如何表示`int []`?(哎呀,仿制药在很长一段时间内都不存在.)你可以通过使用所有集合的链表来逃避没有数组,但效率会很差. (2认同)

Mic*_*rdt 18

它在Java语言规范中定义:

数组类型的成员是以下所有成员:

  • public final字段length,包含数组的组件数.length可能是正数或零.

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


nem*_*035 15

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

public final字段长度,包含数组的组件数.

不是"完全"正确的.

字段长度包含放置组件的可用位置数,而不是阵列中存在的组件数.因此它表示分配给该阵列的总可用内存,而不是填充了多少内存.

阵列内存分配

例:

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);         
}
Run Code Online (Sandbox Code Playgroud)

输出:

Length of int[]:        5
Length of String[]:     5
Length of StuffClass[]: 5
Run Code Online (Sandbox Code Playgroud)

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

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());
Run Code Online (Sandbox Code Playgroud)

输出:

List size:  0
List size:  1
List size:  2
Run Code Online (Sandbox Code Playgroud)

  • 这是正确的,因为所有元素都初始化为零。数组不能为“空” (2认同)

Mas*_*uso 5

它是公共最终字段,包含数组的组件数(长度可以是正数或零)

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

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());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

更多信息

10.7阵列成员

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