Duplicata possible:
Les constantes de tableaux ne peuvent être utilisées qu'en cas d'erreur d'initialisation
J'étudiais les tableaux, et je suis passé par cette méthode de raccourci pour déclarer et initialiser un tableau sur une seule ligne. Par exemple,
int[] a = {1, 2, 3, 4, 5};
Mais quand j'ai essayé de faire le code suivant, j'ai eu cette erreur du compilateur disant "Les constantes de tableau ne peuvent être utilisées que dans l'initialiseur".
int[] a;
a = {1, 2, 3, 4};
Pourquoi
Ce n'est pas autorisé parce que JLS le dit . La syntaxe n'est autorisée que dans les déclarations et dans les expressions de création de tableau.
Ces derniers offrent un autre moyen d'obtenir le même résultat:
int[] a;
a = new int[]{1, 2, 3, 4};
Quant à la véritable raison sous-jacente pour exiger le new T[]
, ma supposition est la suivante. Considérez l'initialiseur de tableau suivant:
{1, 2, 3, 4}
Il peut être utilisé pour initialiser des tableaux de différents types:
new int[]{1, 2, 3, 4};
new float[]{1, 2, 3, 4};
new double[]{1, 2, 3, 4};
Si la new T[]
peu n'était pas nécessaire, je soupçonne que le nu {1, 2, 3, 4}
pourrait causer des difficultés lors de l'analyse sémantique. Ici, je pense à des cas comme:
void f(float[] x) { ... }
void f(double[] x) { ... }
void g() {
f({1, 2, 3, 4});
}
Si cette syntaxe était autorisée, la spécification de langue devrait gérer la complexité du choix de la fonction à appeler.
Dans la même veine, il n'est pas clair quel devrait être le type de {null}
. Ça peut être Object[]
, Integer[]
, Serializable[]
etc.
Et enfin, le tableau vide {}
serait le plus délicat de tous. Ici, nous ne pouvons même pas dire s'il s'agit d'un tableau d'objets ou d'un tableau de scalaires.
Au lieu de traiter toutes ces complexités, il semble que les concepteurs de langage aient choisi de les éviter en exigeant le new T[]
syntaxe.
La réponse courte est car la spécification de langue le dit .
Et pourquoi? Je soupçonne que c'est à de taper . Dans le premier cas, l'analyseur/compilateur sait que c'est dans le contexte de l'initialisation d'une variable de tableau, et donc les accolades peuvent être déduites comme étant un initialiseur de tableau.
Dans ce dernier cas, la ligne ne précise pas immédiatement ce que signifient les accolades. Vraisemblablement, le typer s'exécute à une phase ultérieure de l'analyse, de sorte qu'il n'était pas possible d'en déduire simplement le sens.
Cet argument semble avoir du poids dans la mesure où vous pouvez utiliser une syntaxe très similaire si vous déclarez spécifiquement (et techniquement de manière redondante) le type à nouveau:
int[] a;
// then later
a = new int[] { 1, 2, 3, 4 };
La seule réponse que vous pouvez obtenir est de nature philosophique. La décision de ne pas autoriser le type de tableau implicite est conforme au principe général de conception de Java pour garder les choses simples et évidentes. Dans le même ordre d'idées, vous pourriez vous demander pourquoi chaque downcast doit être explicite, ou chaque conversion de type rétrécie. Java est un langage à col bleu et évident + explicite est sa valeur fondamentale.
I Java vous ne pouvez initialiser un tableau qu'en utilisant la première méthode. Vous ne pouvez pas affecter un tableau. Comprendre pourquoi pourrait impliquer une théorie sur la façon dont les tableaux sont implémentés. Le compilateur doit savoir quelle taille un tableau quand le tableau est déclaré donc avec la déclaration et l'initialisation sur la première ligne, le compilateur peut déduire la taille mais pas avec la seconde.