Dove viene definita la proprietà length dell'array?


263

Possiamo determinare la lunghezza di un ArrayList<E>usando il suo metodo pubblico size(), come

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

Allo stesso modo possiamo determinare la lunghezza di un Arrayoggetto usando la lengthproprietà

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

Considerando che il size()metodo di ArrayListè definito all'interno della ArrayListclasse, dov'è questa lengthproprietà di Arraydefined?


In termini di organizzazione delle domande, suggerirei di porre la tua domanda "dov'è definita la proprietà length di Array?" prima di tutte le spiegazioni per evitare che il tuo post sembri un tutorial per principianti.
NoName,

Risposte:


250

Le matrici sono oggetti speciali in Java, hanno un attributo semplice chiamato lengthche è final.

Non esiste una "definizione di classe" di un array (non è possibile trovarlo in alcun file .class), fanno parte del linguaggio stesso.

10.7. Membri dell'array

I membri di un tipo di array sono tutti i seguenti:

  • Il public finalcampo length, che contiene il numero di componenti dell'array. lengthpuò essere positivo o zero.
  • Il publicmetodo clone, che sostituisce il metodo con lo stesso nome in classe Objecte non genera eccezioni verificate. Il tipo restituito del clonemetodo di un tipo di array T[]è T[].

    Un clone di un array multidimensionale è superficiale, vale a dire che crea solo un singolo nuovo array. I subarray sono condivisi.

  • Tutti i membri ereditati dalla classe Object; l'unico metodo Objectche non è ereditato è il suo clonemetodo.

risorse:


84
Si noti inoltre che ArrayList.size()fornisce il numero di oggetti effettivamente memorizzati nell'array mentre myArray.length( []) fornisce la "capacità". Cioè, se per myArray = new int[10];, restituisce 10. Non è il numero di oggetti che hai inserito nell'array.
wmorrison365,

1
@Colin In che modo gli oggetti array sono così speciali, intendo perché i designer devono renderli speciali e perché non fornire un file di classe di un array?
Vikas Verma,

5
@VikasVerma Perché le matrici non sono come oggetti? A causa della storia. Quando fu progettato Java, la maggior parte dei tentativi di innovazione del linguaggio fallirono quando non furono simili a C nella sintassi e nello stile. Quindi C ++, Objective-C e Java furono tra i pochi linguaggi a sfuggire all'oscurità durante quell'era. Java è stato progettato consapevolmente per includere parentesi graffe, primitive e array semplici per apparire familiari ai programmatori mainstream del giorno. Guarda le interviste con James Gosling e altre persone del sole. Alcune persone restano fedeli alle Collezioni per puro OOP ed evitano array semplici.
Basil Bourque,

1
@VikasVerma, ad un certo punto, Java deve essere basato su una tecnologia di livello inferiore. Se java non esiste, non puoi costruirlo con java. Devi usare C ++ (o qualcos'altro, ma C ++ in questo caso) per creare una compilazione primitiva per il resto di java in modo da avere un contesto per la sua stessa esistenza. Non puoi avere classi per tutto senza alla fine toccare il fondo dove lo codice in C ++. Come costruiresti esattamente un array in Java? Se non è possibile utilizzare a Listperché utilizza matrici nelle loro implementazioni.
Alexander Bird

se vuoi rispondere così com'è , allora stackoverflow.com/a/50506451/1059372
Eugene

114

E ' "speciale" in fondo, con la propria istruzione bytecode: arraylength. Quindi questo metodo:

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

viene compilato in bytecode in questo modo:

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

Quindi non si accede come se fosse un campo normale. Infatti, se provi a ottenerlo come se fosse un campo normale, come questo, fallisce:

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

Quindi, sfortunatamente, la descrizione JLS di ogni tipo di array con un campo finale pubblico lengthè in qualche modo fuorviante :(


1
non ricordo esattamente una citazione di Albert Einstein ma quello che dice è che "la gente capisce una cosa molto bene può solo spiegarla in modo molto più semplice" penso che ti vada molto bene :)
JAVA

@Jon Skeet Quanto è speciale l'oggetto array, intendo perché i designer devono renderlo speciale e perché non fornire un file di classe di un array?
Vikas Verma,

2
@VikasVerma: pensa alle dimensioni di un oggetto array. Tutti gli altri tipi hanno una dimensione fissa: ogni istanza ha la stessa dimensione, mentre le matrici variano in base alla loro lunghezza. Questo è solo un esempio. Se pensi di poter ottenere gli stessi risultati senza usare nulla di speciale, come pensi che sarebbero i campi di una classe di array? Come rappresenteresti int[]quando i generici non si applicano ai tipi primitivi? (E diamine, i generici non esistevano da molto tempo in ogni caso.) Si potrebbe ottenere via senza le matrici utilizzando le liste collegate per tutte le collezioni, ma sarebbe terribile per l'efficienza.
Jon Skeet,

@JonSkeet Ma per quanto riguarda il tipo di classe StringBuffer ha anche dimensioni fisse? Sì, in effetti stavo pensando ai generici, ma tu mi fai notare prima che lo chiedessi Grazie.
Vikas Verma,

@VikasVerma: Sì, la StringBufferclasse stessa sì, perché contiene un riferimento a char[](o almeno, non so se lo fa ancora, off-hand). Quindi mentre a StringBuilderè responsabile di più memoria, le dimensioni e il layout immediati sono fissi.
Jon Skeet,

18

È definito nelle specifiche del linguaggio Java :

I membri di un tipo di array sono tutti i seguenti:

  • Il public finalcampo length, che contiene il numero di componenti dell'array. lengthpuò essere positivo o zero.

Poiché esiste un numero illimitato di tipi di array (per ogni classe esiste un tipo di array corrispondente e quindi esistono array multidimensionali), non possono essere implementati in un file di classe; la JVM deve farlo al volo.


15

Anche se questa non è una risposta diretta alla domanda, è un'aggiunta all'argomento .lengthvs. .size()Stavo cercando qualcosa correlato a questa domanda, quindi quando mi sono imbattuto ho notato che le definizioni fornite qui

La lunghezza del campo finale pubblico, che contiene il numero di componenti dell'array .

non è "esattamente" corretto.

La lunghezza del campo contiene il numero di posizioni disponibili per inserire un componente, non il numero di componenti presenti nell'array. Quindi rappresenta la memoria disponibile totale allocata a quell'array, non la quantità di memoria occupata.

Allocazione della memoria di array

Esempio:

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

Produzione:

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

Tuttavia, la .size()proprietà di the ArrayListfornisce il numero di elementi nell'elenco:

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

Produzione:

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

1
È corretto, poiché tutti gli elementi sono inizializzati su zero. Le matrici non possono essere "vuote"
Guido

Bene, questo è esattamente quello che ho detto. Non è "esattamente" corretto. Ha ancora una lunghezza di 5 anche se non è stato aggiunto nulla all'array. Pertanto non contiene "esattamente" il numero di elementi nell'array. Il tuo commento è solo un'aggiunta alla mia risposta, non un motivo per renderlo errato.
nem035,

Potrebbe essere "errato" se si tenta di distinguere tra nullelementi non nulli. Ma la distinzione non funziona. Dopotutto, size()di (diciamo) a Listpuò includere nullanche valori.
Stephen C

Sì, essenzialmente il mio punto era che sizesi comporta in modo dinamico, mentre lengthè una proprietà statica ... il fatto che lo spazio non riempito rimanente in un array venga inizializzato su " Non Valori " (a seconda del tipo) non contraddice davvero questo punto.
nem035

5

è il campo finale pubblico, che contiene il numero di componenti dell'array (la lunghezza può essere positiva o zero)

Un array ha quindi gli stessi campi e metodi pubblici della seguente classe:

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

maggiori informazioni su

10.7 Membri dell'array

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


0

Per rispondere così com'è, dov'è definita questa proprietà di lunghezza dell'array ? In uno speciale Object header.

Facile da vedere tramite JOL

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

Una delle linee di questo output sarà:

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

Di solito gli oggetti hanno due intestazioni (segno e klass), gli array ne hanno uno in più che occupa sempre 4 bytesin lunghezza, come sizeè un int.


-1

La lunghezza della parola chiave si comporta come un dato archiviato definito. Quando si utilizza in un array, è possibile utilizzarlo per accedere al numero di elementi in un array. Per quanto riguarda String [], possiamo invocare il metodo length () definito nella classe String. Per quanto riguarda ArrayList, possiamo usare il metodo size () definito in ArrayList. Si noti che quando si crea un elenco di array con ArrayList <> (capacità), la dimensione iniziale () di questo elenco di array è zero poiché non è presente alcun elemento.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.