Java exige que si vous appelez this() ou super() dans un constructeur, ce doit être la première déclaration. Pourquoi ?
Par exemple :
public class MyClass {
public MyClass(int x) {}
}
public class MySubClass extends MyClass {
public MySubClass(int a, int b) {
int c = a + b;
super(c); // COMPILE ERROR
}
}
Le compilateur Sun dit "l'appel à super doit être la première déclaration du constructeur". Le compilateur Eclipse dit "L'appel au constructeur doit être la première déclaration dans un constructeur".
Cependant, vous pouvez contourner ce problème en réorganisant un peu le code :
public class MySubClass extends MyClass {
public MySubClass(int a, int b) {
super(a + b); // OK
}
}
Voici un autre exemple :
public class MyClass {
public MyClass(List list) {}
}
public class MySubClassA extends MyClass {
public MySubClassA(Object item) {
// Create a list that contains the item, and pass the list to super
List list = new ArrayList();
list.add(item);
super(list); // COMPILE ERROR
}
}
public class MySubClassB extends MyClass {
public MySubClassB(Object item) {
// Create a list that contains the item, and pass the list to super
super(Arrays.asList(new Object[] { item })); // OK
}
}
Donc, c'est ne vous empêche pas d'exécuter la logique avant l'appel au super. Il vous empêche simplement d'exécuter une logique que vous ne pouvez pas faire tenir dans une seule expression.
Il existe des règles similaires pour appeler this()
. Le compilateur dit "l'appel à this doit être la première déclaration du constructeur".
Pourquoi le compilateur a-t-il ces restrictions ? Pouvez-vous donner un exemple de code où, si le compilateur n'avait pas cette restriction, quelque chose de mauvais se produirait ?
201 votes
Tellement de haine pour ça. Pourquoi ne peut-il pas y avoir une exception "objet pas encore construit", pour que je n'aie pas à tout mettre dans une seule ligne ?
9 votes
Une bonne question. J'ai commencé un projet similaire en valjok.blogspot.com/2012/09/ et programmers.exchange où je montre qu'il y a des cas où les sous-champs doivent être initialisés avant le super(). Ainsi, la fonctionnalité ajoute à la complexité de faire les choses alors qu'il n'est pas clair si les impacts positifs concernant la "sécurité du code" surpondèrent les négatifs. Oui, il y a des conséquences négatives à ce que super soit toujours le premier. Il est surprenant que personne ne le mentionne. Je pense que c'est une question conceptuelle qui doit être posée dans le cadre de l'échange de programmeurs.
3 votes
Merci de décrire clairement comment contourner cette restriction !
0 votes
Vous devez upvoter cette explication, stackoverflow.com/a/1792054/1083704
48 votes
Le pire, c'est qu'il s'agit d'une restriction purement Java. Au niveau du bytecode, il n'y a aucune restriction de ce type.
2 votes
Eh bien, il serait impossible d'avoir cette restriction au niveau du bytecode - tous les exemples de cet article violeraient une telle restriction, même ceux qui regroupent toute la logique dans une seule expression.
0 votes
Duplicata possible de L'appel à super() doit être la première déclaration dans le corps du constructeur.