Array-Initialisierungssyntax, wenn keine Deklaration vorhanden ist

141

Ich kann schreiben:

AClass[] array = {object1, object2}

Ich kann auch schreiben:

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

aber ich kann nicht schreiben:

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

Warum wird dies von Java blockiert?

Ich weiß, wie man es umgeht, aber von Zeit zu Zeit wäre es einfacher.

Beispielsweise:

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

Diese einfache Frage nervt mich, seit ich gelernt habe, wie man mit Arrays in Java spielt.

Jason Rogers
quelle
Entschuldigung für das Textformat, aber aus irgendeinem Grund werden in China die Schaltflächen für das Textlayout nicht angezeigt: S
Jason Rogers
Stellen Sie für Code einfach sicher, dass er mit 4 oder mehr Leerzeichen eingerückt ist.
Mat
Das andere Problem ist, dass der eingefügte Code TAB-Zeichen enthielt. Dies bringt die Formatierung durcheinander.
Stephen C
Oki, danke, Eclipse verwendet Tabulatoren in der Einrückung. Wenn ich also kopiere und einfüge, werden die Dinge durcheinander gebracht. danke für die Bearbeitung
Jason Rogers
Eclipse kann und sollte so konfiguriert werden, dass keine TAB-Zeichen zum Einrücken verwendet werden. Bitte benutzen Sie das nicht als Entschuldigung.
Stephen C

Antworten:

137

Warum wird dies von Java blockiert?

Sie müssten die Java-Designer fragen. Es könnte einen subtilen grammatikalischen Grund für die Einschränkung geben. Beachten Sie, dass einige der Konstrukte zur Array-Erstellung / -Initialisierung nicht in Java 1.0 enthalten waren und (IIRC) in Java 1.1 hinzugefügt wurden.

Aber "warum" ist unerheblich ... die Einschränkung ist da und man muss damit leben.

Ich weiß, wie man es umgeht, aber von Zeit zu Zeit wäre es einfacher.

Sie können dies schreiben:

AClass[] array;
...
array = new AClass[]{object1, object2};
Stephen C.
quelle
9
Ohne die neue Deklaration würde es keinen Unterschied zwischen einem Anweisungsblock und einem Array-Initialisierer geben (wie in Javascript, was irreführend sein kann)
bestsss
10
Es wäre verwirrend ... und schwer zu analysieren. Überlegen Sie, ob {o1()}es sich um einen gültigen Ausdruck und {o1();}einen gültigen Anweisungsblock handelt. Der Parser muss zum '}' oder ';' gelangen. bevor es die beiden Fälle unterscheiden kann. Das grammatikalische Problem ist überhaupt nicht subtil !!
Stephen C
19

Ich werde versuchen, die Warum-Frage zu beantworten: Das Java-Array ist im Vergleich zu Klassen wie ArrayList, die dynamischer sind, sehr einfach und rudimentär. Java möchte zur Deklarationszeit wissen, wie viel Speicher für das Array zugewiesen werden soll. Eine ArrayList ist viel dynamischer und kann im Laufe der Zeit unterschiedlich groß sein.

Wenn Sie Ihr Array mit der Länge zwei initialisieren und sich später herausstellt, dass Sie eine Länge von drei benötigen, müssen Sie das, was Sie haben, wegwerfen und ein ganz neues Array erstellen. Daher das 'neue' Schlüsselwort.

In Ihren ersten beiden Beispielen geben Sie zur Deklarationszeit an, wie viel Speicher zugewiesen werden soll. In Ihrem dritten Beispiel wird der Arrayname zu einem Zeiger auf gar nichts. Wenn Sie ihn initialisieren, müssen Sie daher explizit ein neues Array erstellen, um die richtige Speichermenge zuzuweisen.

Ich würde sagen, dass (und wenn jemand es besser weiß, bitte korrigieren Sie mich) das erste Beispiel

AClass[] array = {object1, object2}

bedeutet eigentlich

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

Die Java-Designer haben es jedoch schneller gemacht, es zu schreiben, wenn Sie das Array zur Deklarationszeit erstellen.

Die vorgeschlagenen Problemumgehungen sind gut. Wenn die Zeit- oder Speichernutzung zur Laufzeit kritisch ist, verwenden Sie Arrays. Wenn dies nicht kritisch ist und Sie Code wünschen, der einfacher zu verstehen und zu verarbeiten ist, verwenden Sie ArrayList.

prograde
quelle
2
Dies ist eine Verknüpfung , wie Sie gesagt haben, Zitiert Oracle: „Alternativ können Sie die Verknüpfung Syntax verwenden , um ein Array zu erstellen und initialisieren“ . Der Grund könnte sein, dass einem Array irgendwann Speicherplatz mit new zugewiesen werden muss . Neu ist in der Verknüpfung implizit enthalten, die Verknüpfung ist jedoch nur in der Deklaration gültig. An anderer Stelle ist keine Verknüpfung zulässig, und neue sind obligatorisch.
Minuten
3
Es tut mir leid, aber Ihr Versuch, die "Warum" -Frage zu beantworten, hält kein Wasser. Der Compiler kann herausfinden, wie groß das Array sein muss, indem er die Ausdrücke zwischen {und und }... zählt, genau wie bei den zulässigen Initialisierungsformularen.
Stephen C
8

Ich kann den Warum-Teil nicht beantworten.

Aber wenn Sie etwas Dynamisches wollen, warum ziehen Sie dann nicht Collection ArrayList in Betracht?

ArrrayList kann von einem beliebigen Objekttyp sein.

Und wenn Sie es als Zwang als Array wollen, können Sie die toArray () -Methode verwenden.

Beispielsweise:

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

Ich hoffe das könnte dir helfen.

Amanpreet
quelle
2
Es ist nicht erforderlich, den Rückgabetyp des Arrays in String [] umzuwandeln. Vertraglich ist das zurückgegebene Array vom gleichen Typ wie das angegebene Array. docs.oracle.com/javase/6/docs/api/java/util/…
Ankur Agarwal
4

Für diejenigen unter Ihnen, die diese monströse new AClass[] { ... }Syntax nicht mögen , hier etwas Zucker:

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

Verwenden Sie diese kleine Funktion, wie Sie möchten:

AClass[] array;
...
array = c(object1, object2);
user123
quelle