Je n'arrive pas à faire fonctionner la réflexion dans un constructeur de classe avec l'héritage. Plus précisément, j'aimerais obtenir toutes les valeurs d'attribut.Réflexion dans le constructeur avec héritage (Java)
Voici une démo pour la mise en œuvre naïve qui ne fonctionne pas:
import java.lang.reflect.Field;
public class SubInitProblem {
public static void main(String[] args) throws IllegalAccessException {
Child p = new Child();
}
}
class Parent {
public int parentVar = 888888;
public Parent() throws IllegalAccessException {
this.showFields();
}
public void showFields() throws IllegalAccessException {
for (Field f : this.getClass().getFields()) {
System.out.println(f + ": " + f.get(this));
}
}
}
class Child extends Parent {
public int childVar = 999999;
public Child() throws IllegalAccessException {
super();
}
}
Cela montrera que childVar
est égal à zéro:
public int Child.childVar: 0
public int Parent.parentVar: 888888
Parce qu'il est pas encore initialisé.
donc je suppose que je vais avoir besoin de ne pas utiliser le constructeur directement, mais plutôt laisser le constructeur complet et puis utilisation showFields
:
import java.lang.reflect.Field;
public class SubInitSolution {
public static void main(String[] args) throws IllegalAccessException {
SolChild p = SolChild.make();
}
}
class SolParent {
public int parentVar = 888888;
protected SolParent() {
}
public static <T extends SolParent> T make() throws IllegalAccessException {
SolParent inst = new SolParent();
inst.showFields();
return (T) inst;
}
public void showFields() throws IllegalAccessException {
for (Field f : this.getClass().getFields()) {
System.out.println(f + ": " + f.get(this));
}
}
}
class SolChild extends SolParent {
public int childVar = 999999;
public SolChild() throws IllegalAccessException {
}
}
Mais cela ne fonctionne pas parce que make
ne retourne pas le type correct pour les sous-classes. (Donc le problème est new SolParent();
).
Quelle est la meilleure façon de résoudre ce problème? J'ai besoin de toutes les sous-classes pour exécuter showFields
, mais je ne peux pas compter sur les faire explicitement.
Dans votre deuxième exemple, pourquoi implémenter une méthode 'make'? Pourquoi ne pas faire juste 'new SolChild(). ShowFields();' – ToYonos
N'appelez pas de telles méthodes d'un constructeur. Ils ne contribuent pas à l'initialisation et n'appartiennent donc pas aux constructeurs. –
@ToYonos Parce que les gens qui utilisent ma classe pourraient alors oublier de le faire – Mark