Syntaxe d'initialisation du tableau lorsqu'il n'est pas dans une déclaration

141

Je peux écrire:

AClass[] array = {object1, object2}

Je peux aussi écrire:

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

mais je ne peux pas écrire:

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

Pourquoi est-ce bloqué par Java?

Je sais comment contourner ce problème, mais de temps en temps, ce serait plus simple.

Par exemple:

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

Cette question simple qui me dérange depuis que j'ai appris à jouer avec des tableaux en Java.

Jason Rogers
la source
Désolé pour le format du texte, mais pour une raison quelconque en Chine, les boutons de mise en page du texte n'apparaissent pas: S
Jason Rogers
pour le code, assurez-vous simplement qu'il est indenté avec 4 espaces ou plus.
Mat
l'autre problème est que vous aviez des caractères TAB dans le code que vous avez collé. Cela gâche le formatage.
Stephen C
Oki merci, eclipse utilise des tabulations dans l'indentation, donc quand je copie coller ça gâche les choses. merci pour le montage
Jason Rogers
Eclipse peut et doit être reconfiguré pour ne pas utiliser les caractères TAB pour l'indentation. Veuillez ne pas utiliser cela comme une excuse.
Stephen C

Réponses:

137

Pourquoi est-ce bloqué par Java?

Il faudrait demander aux concepteurs Java. Il peut y avoir une raison grammaticale subtile à la restriction. Notez que certaines des constructions de création / initialisation de tableau n'étaient pas dans Java 1.0, et (IIRC) a été ajouté dans Java 1.1.

Mais "pourquoi" est sans importance ... la restriction est là, et vous devez vivre avec.

Je sais comment contourner ce problème, mais de temps en temps, ce serait plus simple.

Vous pouvez écrire ceci:

AClass[] array;
...
array = new AClass[]{object1, object2};
Stephen C
la source
9
sans la nouvelle déclaration, il n'y aurait aucune différence entre un bloc d'instructions et un initialiseur de tableau (comme en javascript, ce qui peut être trompeur}
bestsss
10
Ce serait déroutant ... et difficile à analyser. Considérez si {o1()}était une expression valide et {o1();}était un bloc d'instructions valide. L'analyseur doit accéder au '}' ou ';' avant de pouvoir distinguer les deux cas. Le problème grammatical n'est pas du tout subtil !!
Stephen C
19

Je vais essayer de répondre à la question du pourquoi: le tableau Java est très simple et rudimentaire par rapport aux classes comme ArrayList, qui sont plus dynamiques. Java veut savoir au moment de la déclaration combien de mémoire doit être allouée au tableau. Une ArrayList est beaucoup plus dynamique et sa taille peut varier dans le temps.

Si vous initialisez votre tableau avec une longueur de deux, et plus tard, il s'avère que vous avez besoin d'une longueur de trois, vous devez jeter ce que vous avez et créer un tout nouveau tableau. Par conséquent, le mot-clé «nouveau».

Dans vos deux premiers exemples, vous indiquez au moment de la déclaration la quantité de mémoire à allouer. Dans votre troisième exemple, le nom du tableau devient un pointeur vers rien du tout, et par conséquent, lorsqu'il est initialisé, vous devez créer explicitement un nouveau tableau pour allouer la bonne quantité de mémoire.

Je dirais que (et si quelqu'un sait mieux, veuillez me corriger) le premier exemple

AClass[] array = {object1, object2}

signifie en fait

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

mais ce que les concepteurs de Java ont fait, c'était de faire un moyen plus rapide de l'écrire si vous créez le tableau au moment de la déclaration.

Les solutions de contournement suggérées sont bonnes. Si le temps ou l'utilisation de la mémoire est critique au moment de l'exécution, utilisez des tableaux. Si ce n'est pas critique et que vous voulez un code plus facile à comprendre et à utiliser, utilisez ArrayList.

prograde
la source
2
Il s'agit d'un raccourci comme vous l'avez indiqué, citant Oracle: "Vous pouvez également utiliser la syntaxe de raccourci pour créer et initialiser un tableau" . La raison peut-être qu'un tableau doit avoir de l'espace en mémoire en utilisant new à un moment donné. Nouveau est implicite dans le raccourci, mais le raccourci n'est valide que dans la déclaration. Ailleurs, aucun raccourci n'est autorisé et le nouveau est obligatoire.
min
3
Je suis désolé, mais votre tentative de répondre à la question «pourquoi» ne tient pas la route. Le compilateur serait capable de déterminer la taille du tableau nécessaire en comptant les expressions entre le {et le }... comme il le fait pour les formulaires d'initialisation qui sont autorisés.
Stephen C
8

Je ne peux pas répondre à la partie pourquoi.

Mais si vous voulez quelque chose de dynamique, pourquoi ne pas envisager Collection ArrayList.

ArrrayList peut être de n'importe quel type d'objet.

Et si vous le voulez sous forme de tableau, vous pouvez utiliser la méthode toArray () dessus.

Par exemple:

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

J'espère que cela pourrait vous aider.

Amanpreet
la source
2
Il n'est pas nécessaire de convertir le type de retour du tableau en String []. Par contrat, le tableau retourné est du même type que le tableau spécifié. docs.oracle.com/javase/6/docs/api/java/util/…
Ankur Agarwal
4

Pour ceux d'entre vous qui n'aiment pas cette monstrueuse new AClass[] { ... }syntaxe, voici du sucre:

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

Utilisez cette petite fonction comme vous le souhaitez:

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