Sintassi di inizializzazione dell'array quando non in una dichiarazione


141

Posso scrivere:

AClass[] array = {object1, object2}

Posso anche scrivere:

AClass[] array = new AClass[2];
...
array[0] = object1;
array[1] = object2;

ma non riesco a scrivere:

AClass[] array;
...
array = {object1, object2};

Perché questo è bloccato da Java?

So come aggirarlo, ma di tanto in tanto sarebbe più semplice.

Per esempio:

public void selectedPointsToMove(cpVect coord) {

    if (tab == null) {
        if (arePointsClose(coord, point1, 10)) {
            cpVect[] tempTab = {point1};
            tab = tempTab;
        } else if (arePointsClose(point2, coord, 10)) {
            cpVect[] tempTab = {point2};
            tab = tempTab;
        } else {
            cpVect[] tempTab = {point1,point2};
            tab = tempTab;
        }
    }
}

Questa semplice domanda che mi ha infastidito da quando ho imparato a giocare con le matrici in Java.


Mi dispiace per il formato del testo, ma per qualche motivo in Cina i pulsanti di layout del testo non vengono visualizzati: S
Jason Rogers

per il codice, assicurati solo che sia rientrato con 4 o più spazi.
Mat

l'altro problema è che avevi caratteri TAB nel codice che hai incollato. Questo incasina la formattazione.
Stephen C,

Oki grazie, eclipse usa le linguette nel rientro, quindi quando copio incolla fa confusione. grazie per la modifica
Jason Rogers,

Eclipse può e deve essere riconfigurato per non utilizzare i caratteri TAB per il rientro. Per favore, non usarlo come scusa.
Stephen C,

Risposte:


137

Perché questo è bloccato da Java?

Dovresti chiedere ai designer Java. Potrebbe esserci qualche sottile motivo grammaticale per la restrizione. Si noti che alcuni dei costrutti di creazione / inizializzazione di array non erano in Java 1.0 e (IIRC) sono stati aggiunti in Java 1.1.

Ma "perché" è irrilevante ... la restrizione esiste e devi conviverci.

So come aggirarlo, ma di tanto in tanto sarebbe più semplice.

Puoi scrivere questo:

AClass[] array;
...
array = new AClass[]{object1, object2};

9
senza la nuova dichiarazione non ci sarebbe alcuna differenza tra un blocco di istruzioni e l'inizializzatore di array (come in javascript, che può essere fuorviante}
bestsss

10
Si sarebbe essere fonte di confusione ... e difficile da analizzare. Considera se {o1()}era un'espressione valida ed {o1();}era un blocco di istruzioni valido. Il parser deve arrivare a '}' o ';' prima che possa distinguere i due casi. Il problema grammaticale non è affatto sottile !!
Stephen C

19

Cercherò di rispondere alla domanda sul perché: l'array Java è molto semplice e rudimentale rispetto alle classi come ArrayList, che sono più dinamiche. Java vuole sapere al momento della dichiarazione quanta memoria dovrebbe essere allocata per l'array. Una ArrayList è molto più dinamica e la sua dimensione può variare nel tempo.

Se inizializzi il tuo array con la lunghezza di due, e in seguito si scopre che hai bisogno di una lunghezza di tre, devi buttare via quello che hai e creare un array completamente nuovo. Pertanto la "nuova" parola chiave.

Nei primi due esempi, al momento della dichiarazione si comunica la quantità di memoria da allocare. Nel tuo terzo esempio, il nome dell'array diventa un puntatore a nulla e, quindi, quando viene inizializzato, devi creare esplicitamente un nuovo array per allocare la giusta quantità di memoria.

Direi che (e se qualcuno lo sa meglio, per favore correggimi) il primo esempio

AClass[] array = {object1, object2}

in realtà significa

AClass[] array = new AClass[]{object1, object2};

ma quello che hanno fatto i progettisti Java, è stato quello di rendere il modo più veloce per scriverlo se si creava l'array al momento della dichiarazione.

Le soluzioni alternative suggerite sono buone. Se il tempo o l'utilizzo della memoria sono fondamentali in fase di runtime, utilizzare gli array. Se non è critico e vuoi un codice che sia più facile da capire e con cui lavorare, usa ArrayList.


2
Questo è un collegamento come hai detto, Citando Oracle: "In alternativa, puoi usare la sintassi del collegamento per creare e inizializzare un array" . La ragione forse è che a un array deve essere dato un po 'di spazio in memoria usando new ad un certo punto. Nuovo è implicito nel collegamento, ma il collegamento è valido solo nella dichiarazione. Altrove, non è consentito alcun collegamento e il nuovo è obbligatorio.
minuti

3
Mi dispiace, ma il tuo tentativo di rispondere alla domanda "perché" non trattiene l'acqua. Il compilatore sarebbe in grado di capire quanto doveva essere grande l'array contando le espressioni tra il {e il }... proprio come fa per i moduli di inizializzazione consentiti.
Stephen C,

8

Non posso rispondere al perché parte.

Ma se vuoi qualcosa di dinamico, allora perché non prendere in considerazione Collection ArrayList.

ArrrayList può essere di qualsiasi tipo di oggetto.

E se come coazione lo vuoi come un array puoi usare il metodo toArray () su di esso.

Per esempio:

            ArrayList<String> al = new ArrayList<String>();
            al.add("one");
            al.add("two");
            String[] strArray = (String[]) al.toArray(new String[0]);

Spero che questo possa aiutarti.


2
Non è necessario eseguire il cast del tipo restituito dell'array su String []. Per contratto, l'array restituito è dello stesso tipo dell'array specificato. docs.oracle.com/javase/6/docs/api/java/util/…
Ankur Agarwal

4

Per quelli di voi, a cui non piace questa new AClass[] { ... }sintassi mostruosa , ecco un po 'di zucchero:

public AClass[] c(AClass... arr) { return arr; }

Usa questa piccola funzione come preferisci:

AClass[] array;
...
array = c(object1, object2);
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.