La raison est une spécification quelque peu surconçue.
L'idée derrière le fait que les expressions ne sont pas des instructions valides est qu'elles ne réalisent absolument rien. 5 + 2;
ne fait rien en soi. Vous devez lui attribuer quelque chose, ou le passer à quelque chose, sinon pourquoi l'écrire?
Il y a cependant des exceptions: Les expressions qui, en elles-mêmes, auront (ou pourraient éventuellement avoir) des effets secondaires. Par exemple, alors que cela est illégal:
void foo(int a) {
a + 1;
}
Ceci ne l'est pas:
void foo(int a) {
a++;
}
Cela est dû au fait que, en soi, a++
n'est pas complètement inutile, cela change effectivement les choses (a est modifié en faisant cela). En réalité, 'ignorer la valeur' (vous ne faites rien avec a + 1
dans cet extrait) est acceptable si le fait de produire la valeur en soi provoque d'autres choses: Après tout, c'est peut-être ce que vous vouliez depuis le début.
Pour cette raison, invoquer des méthodes est également une expressiond'instruction légitime, et en fait il est très courant d'invoquer des méthodes (même celles qui ne retournent pas void
), en ignorant la valeur de retour. Pour les méthodes void, c'est le seul moyen légal de les invoquer, même.
Les constructeurs sont techniquement des méthodes et peuvent avoir des effets secondaires. Il est extrêmement improbable, et assez mauvais en terme de style de code, que cette méthode:
void doStuff() {
new Something();
}
soit du code 'sensé', mais il pourrait théoriquement être écrit, aussi mauvais que cela puisse être: Le constructeur de la classe Something
peut faire quelque chose d'utile et peut-être est-ce tout ce que vous voulez faire ici: Faire exécuter ce constructeur, faire la chose utile, puis prendre l'objet créé et le jeter immédiatement à la poubelle. Bizarre, mais, d'accord. Vous êtes le programmeur.
En contraste avec:
new Something[10];
Ceci est différent: Le compilateur sait ce que fait le 'constructeur' de tableau. Et ce qu'il fait est pas utile du tout - il crée un objet et renvoie une référence à l'objet, et c'est tout ce qui se passe. Si vous jetez instantanément la référence à la poubelle, alors toute l'opération a été une perte de temps totale, et vous n'avez sûrement pas l'intention de ne rien faire d'utile avec une déclaration aussi bizarre, donc les concepteurs du compilateur ont pensé qu'il était préférable de simplement vous interdire de l'écrire.
Ce 'oh là là ce code n'a aucun sens donc je ne le compilerai pas' est très limité et principalement un aspect obsolète de la spécification originale du compilateur; il n'a jamais été mis à jour et ce n'est pas une bonne façon de s'assurer que le code est sensé; il existe toutes sortes d'outils de linting là-bas qui vont beaucoup plus loin pour trouver du code qui ne peut tout simplement pas aller, donc si vous vous souciez de ce genre de chose, investissez dans l'apprentissage de ceux-ci.
Néanmoins, la spécification java 1.0 avait ces trucs intégrés et il n'y a pas de raison particulièrement bonne de supprimer cet aspect de la spécification java, donc cela reste, et la construction d'un nouveau tableau n'est pas une ExpressionStatement valide.
Comme le dit JLS §14.8, en particulier, une ClassInstanceCreationExpression
est dans la liste des expressionsinstructions valides. Cliquez sur ce mot pour accéder à la définition de ClassInstanceCreationExpression
et vous verrez qu'il fait spécifiquement référence à l'invocation des constructeurs, et pas à la construction de tableau.
Ainsi, le JLS est spécifique et exige ce comportement. javac suit simplement la spécification.