¿Dónde se define la propiedad de la longitud de la matriz?

Podemos determinar la longitud de una ArrayList utilizando su size() método público size() , como

 ArrayList arr = new ArrayList(10); int size = arr.size(); 

Del mismo modo, podemos determinar la longitud de un objeto Array utilizando la propiedad de length

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

Mientras que el método size() de ArrayList se define dentro de la clase ArrayList , ¿dónde se define esta propiedad de length de Array ?

Las matrices son objetos especiales en java, tienen un atributo simple llamado length que es final .

No existe una “definición de clase” de una matriz (no puede encontrarla en ningún archivo .class), son parte del lenguaje en sí.

10.7. Array Members

Los miembros de un tipo de matriz son todos los siguientes:

  • La length campo final public , que contiene la cantidad de componentes de la matriz. length puede ser positiva o cero.
  • El método public clone , que anula el método del mismo nombre en la clase Object y no arroja excepciones marcadas. El tipo de devolución del método de clone de una matriz tipo T[] es T[] .

    Un clon de una matriz multidimensional es superficial, lo que quiere decir que solo crea una nueva matriz. Subarrays son compartidos.

  • Todos los miembros heredados de la clase Object ; el único método de Object que no se hereda es su método de clone .

Recursos:

  • JLS – Matrices

Es “especial” básicamente, con su propia instrucción bytecode: arraylength . Entonces este método:

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

se comstack en bytecode como este:

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

Por lo tanto, no se accede como si fuera un campo normal. De hecho, si intentas obtenerlo como si fuera un campo normal, como este, falla:

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

Desafortunadamente, la descripción de JLS de cada tipo de matriz con una length campo final pública es algo engañosa 🙁

Está definido en la especificación del lenguaje Java :

Los miembros de un tipo de matriz son todos los siguientes:

  • La length campo public final , que contiene la cantidad de componentes de la matriz. length puede ser positiva o cero.

Como hay un número ilimitado de tipos de matriz (para cada clase hay un tipo de matriz correspondiente y luego hay matrices multidimensionales), no se pueden implementar en un archivo de clase; la JVM tiene que hacerlo sobre la marcha.

Aunque esta no es una respuesta directa a la pregunta, es una adición al .length vs .size() . Estaba investigando algo relacionado con esta pregunta, así que cuando lo encontré noté que la (s) definición (es) proporcionada (s) aquí

La longitud del campo final público, que contiene la cantidad de componentes de la matriz .

no es “exactamente” correcto

La longitud del campo contiene la cantidad de lugares disponibles para poner un componente, no la cantidad de componentes presentes en el conjunto. Por lo tanto, representa la memoria total disponible asignada a esa matriz, no la cantidad de esa memoria que se llena.

Array Memory Allocation

Ejemplo:

 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); } 

Salida:

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

Sin embargo, la propiedad .size() de ArrayList proporciona la cantidad de elementos en la lista:

 ArrayList intsList = new ArrayList(); 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()); 

Salida:

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

es un campo final público, que contiene el número de componentes de la matriz (la longitud puede ser positiva o cero)

Por lo tanto, una matriz tiene los mismos campos públicos y métodos que la siguiente clase:

 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()); } } } 

más información en

10.7 Miembros de matriz

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

La duración de la palabra clave actúa como un archivo de datos definido. Cuando lo usamos en una matriz, podemos usarlo para acceder a la cantidad de elementos en una matriz. En cuanto a String [], podemos invocar el método length () definido en la clase String. Con respecto a ArrayList, podemos usar el método de tamaño () definido en ArrayList. Tenga en cuenta que al crear una lista de matriz con ArrayList <> (capacidad), el tamaño inicial () de esta lista de matriz es cero ya que no hay elemento.

Para responderlo tal como está, ¿ dónde está definida esta propiedad de longitud de la matriz ? En un Object header especial.

Fácil de ver a través de JOL

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

Una de las líneas de esta salida será:

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

Por lo general, los objetos tienen dos encabezados (mark y klass), los arrays tienen uno más que siempre ocupa 4 bytes de longitud, ya que el size es un int .