Onde a propriedade de comprimento de matriz é definida?

Podemos determinar o tamanho de um ArrayList usando seu size() método público size() , como

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

Da mesma forma, podemos determinar o comprimento de um object Array usando a propriedade length

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

Considerando que o método size() de ArrayList é definido dentro da class ArrayList , onde esta propriedade de length de Array definida?

Arrays são objects especiais em java, eles têm um atributo simples chamado length que é final .

Não há “definição de class” de um array (você não pode encontrá-lo em nenhum arquivo .class), eles são parte da própria linguagem.

10.7. Membros da Matriz

Os membros de um tipo de matriz são todos os seguintes:

  • O length campo final public , que contém o número de componentes da matriz. length pode ser positivo ou zero.
  • O clone método public , que substitui o método com o mesmo nome na class Object e não lança exceções verificadas. O tipo de retorno do método clone de um tipo de matriz T[] é T[] .

    Um clone de um array multidimensional é superficial, o que significa que ele cria apenas um novo array. Subarrays são compartilhados.

  • Todos os membros herdados da class Object ; o único método de Object que não é herdado é o seu método clone .

Recursos:

  • JLS – Matrizes

É “especial” basicamente, com sua própria instrução de bytecode: arraylength . Então esse método:

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

é compilado em bytecode como este:

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

Portanto, não é acessado como se fosse um campo normal. De fato, se você tentar obtê-lo como se fosse um campo normal, assim, ele falhará:

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

Então, infelizmente, a descrição JLS de cada tipo de matriz com um length campo final público é um pouco enganosa 🙁

Está definido na especificação da linguagem Java :

Os membros de um tipo de matriz são todos os seguintes:

  • O length campo public final , que contém o número de componentes da matriz. length pode ser positivo ou zero.

Como há um número ilimitado de tipos de matriz (para cada class existe um tipo de matriz correspondente e, em seguida, há matrizes multidimensionais), eles não podem ser implementados em um arquivo de class; a JVM tem que fazer isso em tempo real.

Embora essa não seja uma resposta direta à pergunta, ela é uma adição ao .length vs .size() . Eu estava pesquisando algo relacionado a essa questão, então quando me deparei com isso, notei que a (s) definição (ões) fornecida (s) aqui

O tamanho do campo final público, que contém o número de componentes da matriz .

não está “exatamente” correto.

O comprimento do campo contém o número de locais disponíveis para colocar um componente, não o número de componentes presentes na matriz. Por isso, representa a memory total disponível alocada a essa matriz, e não quanto dessa memory é preenchida.

Alocação de Memória de Matriz

Exemplo:

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

Saída:

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

No entanto, a propriedade .size() da ArrayList fornece o número de elementos na 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()); 

Saída:

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

é o campo final público, que contém o número de componentes da matriz (o comprimento pode ser positivo ou zero)

Uma matriz, portanto, tem os mesmos campos e methods públicos da seguinte class:

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

mais informações em

10,7 membros da matriz

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

O tamanho da palavra-chave funciona como um arquivo de dados definido. Ao usar em uma matriz, podemos usá-lo para acessar quantos elementos em uma matriz. Em relação a String [], podemos invocar o método length () definido na class String. Com relação ao ArrayList, podemos usar o método size () definido no ArrayList. Observe que ao criar uma lista de arrays com ArrayList <> (capacidade), o tamanho inicial () dessa lista de arrays é zero, pois não há nenhum elemento.

Para respondê-lo como é, onde esta propriedade de comprimento da matriz é definida ? Em um Object header especial.

Fácil de ver via JOL

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

Uma das linhas desta saída será:

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

Normalmente os Objetos possuem dois headers (mark e klass), os arrays possuem um mais que sempre ocupa 4 bytes de tamanho, já que size é um int .