S'il para=EEt logique, apr=E8s tout, que les attributs "propres" d'une
classe soient initialis=E9s apr=E8s l'ex=E9cution du super-constructeur, il
me semble que =E7a n'=E9tait pas le cas... Un projet d=E9marr=E9 il y a
longtemps et qui fonctionnait, plante lamentablement en JDK 1.5.0_11 :
public class Toto extends Tata {
List attr =3D new ArrayList<Bibi>();
public Toto(HashMap args) {
super(args);
}
public void doSomething(List bibis) {
this.attr.putBibis(bibis); // NullPointerException !
}
}
public abstract class Tata {
public Tata(HashMap args) {
this.doSomething(args.get("liste_bibis"));
}
public abstract void doSomething(List bibis);
}
Comme on le voit, mon algorithme fait appel, via le super-constructeur
de la classe abstraite, aux attributs de la classe concr=E8te... qui ne
sont plus initialis=E9s =E0 temps.
A part de r=E9aliser l'initialisation dans l'impl=E9mentation de
#doSomething, qq'un voit-il une mani=E8re plus =E9l=E9gante de mettre ce
programme au diapason de la nouvelle JVM ?
Merci d'avance, ToOmS.
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
TestMan
Bonjour à tous,
S'il paraît logique, après tout, que les attributs "propres" d'une classe soient initialisés après l'exécution du super-constructeur, il me semble que ça n'était pas le cas... Un projet démarré il y a longtemps et qui fonctionnait, plante lamentablement en JDK 1.5.0_11 :
public class Toto extends Tata { List attr = new ArrayList<Bibi>();
public Toto(HashMap args) { super(args); } public void doSomething(List bibis) { this.attr.putBibis(bibis); // NullPointerException ! } } public abstract class Tata { public Tata(HashMap args) { this.doSomething(args.get("liste_bibis")); } public abstract void doSomething(List bibis); }
Comme on le voit, mon algorithme fait appel, via le super-constructeur de la classe abstraite, aux attributs de la classe concrète... qui ne sont plus initialisés à temps.
A part de réaliser l'initialisation dans l'implémentation de #doSomething, qq'un voit-il une manière plus élégante de mettre ce programme au diapason de la nouvelle JVM ? Merci d'avance, ToOmS.
Bonjour,
L'ordre en Java est : 1- exécution du super-constructeur 2- initialisation des membres de l'instance 3- execution du reste du constructeur
Comme l'atteste la JLS 3e version http://java.sun.com/docs/books/jls/third_edition/html/execution.html#44670 ( y comprit la JLS 1e version http://java.sun.com/docs/books/jls/first_edition/html/12.doc.html#44670 )
Pour ce qui concerne l'initialisation de votre exemple, pourquoi ne mettez vous pas tout simplement l'appel du .doSomething dans le constructeur de Toto ?
La régression applicative constatée, ne peut donc pas venir d'un changement de spec, Java restant entierement compatible avec le code ascendent (au rajouts de mots-clés et de syntaxe nouvelles près, mais qu'il est possible de désactiver dans le compilateur pour une compatibilité ascendente à 100%).
A+ TM
Bonjour à tous,
S'il paraît logique, après tout, que les attributs "propres" d'une
classe soient initialisés après l'exécution du super-constructeur, il
me semble que ça n'était pas le cas... Un projet démarré il y a
longtemps et qui fonctionnait, plante lamentablement en JDK 1.5.0_11 :
public class Toto extends Tata {
List attr = new ArrayList<Bibi>();
public Toto(HashMap args) {
super(args);
}
public void doSomething(List bibis) {
this.attr.putBibis(bibis); // NullPointerException !
}
}
public abstract class Tata {
public Tata(HashMap args) {
this.doSomething(args.get("liste_bibis"));
}
public abstract void doSomething(List bibis);
}
Comme on le voit, mon algorithme fait appel, via le super-constructeur
de la classe abstraite, aux attributs de la classe concrète... qui ne
sont plus initialisés à temps.
A part de réaliser l'initialisation dans l'implémentation de
#doSomething, qq'un voit-il une manière plus élégante de mettre ce
programme au diapason de la nouvelle JVM ?
Merci d'avance, ToOmS.
Bonjour,
L'ordre en Java est :
1- exécution du super-constructeur
2- initialisation des membres de l'instance
3- execution du reste du constructeur
Comme l'atteste la JLS 3e version
http://java.sun.com/docs/books/jls/third_edition/html/execution.html#44670
( y comprit la JLS 1e version
http://java.sun.com/docs/books/jls/first_edition/html/12.doc.html#44670 )
Pour ce qui concerne l'initialisation de votre exemple, pourquoi ne
mettez vous pas tout simplement l'appel du .doSomething dans le
constructeur de Toto ?
La régression applicative constatée, ne peut donc pas venir d'un
changement de spec, Java restant entierement compatible avec le code
ascendent (au rajouts de mots-clés et de syntaxe nouvelles près, mais
qu'il est possible de désactiver dans le compilateur pour une
compatibilité ascendente à 100%).
S'il paraît logique, après tout, que les attributs "propres" d'une classe soient initialisés après l'exécution du super-constructeur, il me semble que ça n'était pas le cas... Un projet démarré il y a longtemps et qui fonctionnait, plante lamentablement en JDK 1.5.0_11 :
public class Toto extends Tata { List attr = new ArrayList<Bibi>();
public Toto(HashMap args) { super(args); } public void doSomething(List bibis) { this.attr.putBibis(bibis); // NullPointerException ! } } public abstract class Tata { public Tata(HashMap args) { this.doSomething(args.get("liste_bibis")); } public abstract void doSomething(List bibis); }
Comme on le voit, mon algorithme fait appel, via le super-constructeur de la classe abstraite, aux attributs de la classe concrète... qui ne sont plus initialisés à temps.
A part de réaliser l'initialisation dans l'implémentation de #doSomething, qq'un voit-il une manière plus élégante de mettre ce programme au diapason de la nouvelle JVM ? Merci d'avance, ToOmS.
Bonjour,
L'ordre en Java est : 1- exécution du super-constructeur 2- initialisation des membres de l'instance 3- execution du reste du constructeur
Comme l'atteste la JLS 3e version http://java.sun.com/docs/books/jls/third_edition/html/execution.html#44670 ( y comprit la JLS 1e version http://java.sun.com/docs/books/jls/first_edition/html/12.doc.html#44670 )
Pour ce qui concerne l'initialisation de votre exemple, pourquoi ne mettez vous pas tout simplement l'appel du .doSomething dans le constructeur de Toto ?
La régression applicative constatée, ne peut donc pas venir d'un changement de spec, Java restant entierement compatible avec le code ascendent (au rajouts de mots-clés et de syntaxe nouvelles près, mais qu'il est possible de désactiver dans le compilateur pour une compatibilité ascendente à 100%).
A+ TM
ToOmS
On 20 juin, 15:24, TestMan wrote:
[...] Pour ce qui concerne l'initialisation de votre exemple, pourquoi ne mettez vous pas tout simplement l'appel du .doSomething dans le constructeur de Toto ? [...]
Parce que #doSomething est un comportement surchargé mais attendu dans Tata. J'en ait fait une méthode abstraite dans l'exemple pour aller au plus lisible, mais les objets Tata doivent aussi "faire qq chose" à l'instanciation.
Je ne comprends pas pourquoi Ca ne fonctionnait pas. Cette appli "a eu" bien fonctionné, pourtant... J'ai ajouté du code moche : si (this instanceof Toto) alors ((Toto) this).initCollections(); puis this.doSomething(). #initCollections étant toujours appelé dans les autres constructeurs de Toto.
Merci quand même !
On 20 juin, 15:24, TestMan <n...@example.com> wrote:
[...]
Pour ce qui concerne l'initialisation de votre exemple, pourquoi ne
mettez vous pas tout simplement l'appel du .doSomething dans le
constructeur de Toto ?
[...]
Parce que #doSomething est un comportement surchargé mais attendu dans
Tata. J'en ait fait une méthode abstraite dans l'exemple pour aller au
plus lisible, mais les objets Tata doivent aussi "faire qq chose" à
l'instanciation.
Je ne comprends pas pourquoi Ca ne fonctionnait pas. Cette appli "a
eu" bien fonctionné, pourtant...
J'ai ajouté du code moche : si (this instanceof Toto) alors ((Toto)
this).initCollections(); puis this.doSomething().
#initCollections étant toujours appelé dans les autres constructeurs
de Toto.
[...] Pour ce qui concerne l'initialisation de votre exemple, pourquoi ne mettez vous pas tout simplement l'appel du .doSomething dans le constructeur de Toto ? [...]
Parce que #doSomething est un comportement surchargé mais attendu dans Tata. J'en ait fait une méthode abstraite dans l'exemple pour aller au plus lisible, mais les objets Tata doivent aussi "faire qq chose" à l'instanciation.
Je ne comprends pas pourquoi Ca ne fonctionnait pas. Cette appli "a eu" bien fonctionné, pourtant... J'ai ajouté du code moche : si (this instanceof Toto) alors ((Toto) this).initCollections(); puis this.doSomething(). #initCollections étant toujours appelé dans les autres constructeurs de Toto.