Récupère tous les champs (même privés et hérités) de la classe

Je fais un projet universitaire.
Je dois obtenir tous les champs de la classe. Même privé et hérité. J’ai essayé d’obtenir tous les champs déclarés, puis de lancer la super classe et de répéter. Fragment de mon code:

private void listAllFields(Object obj) { List fieldList = new ArrayList(); while (obj != null) { fieldList.addAll(Arrays.asList(obj.getClass().getDeclaredFields())); obj = obj.getClass().getSuperclass().cast(obj); } // rest of code 

Mais ça ne marche pas. tmpObj après le casting est toujours la même classe (pas la superclasse).
J’apprécierai toute aide sur la façon de résoudre les problèmes de casting, ou comment récupérer ces champs de manière différente.

MODIFIER:

Le problème n’est pas d’accéder aux champs, mais d’obtenir les noms des champs!
Je le gère de cette façon:

 private void listAllFields(Object obj) { List fieldList = new ArrayList(); Class tmpClass = obj.getClass(); while (tmpClass != null) { fieldList.addAll(Arrays.asList(tmpClass .getDeclaredFields())); tmpClass = tmpClass .getSuperclass(); } // rest of code 

 obj = obj.getClass().getSuperclass().cast(obj); 

Cette ligne ne fait pas ce que vous attendez de lui. Lancer un object ne le change pas réellement, il dit simplement au compilateur de le traiter comme autre chose.

Par exemple, vous pouvez créer une List dans une Collection , mais celle-ci restra toujours une liste.

Cependant, passer en revue les super-classes pour accéder aux champs fonctionne bien sans conversion:

 Class current = yourClass; while(current.getSuperclass()!=null){ // we don't want to process Object.class // do something with current's fields current = current.getSuperclass(); } 

BTW, si vous avez access à Spring Framework, il existe une méthode pratique pour parcourir les champs d’une classe et toutes les super-classes:
ReflectionUtils.doWithFields(baseClass, FieldCallback)
(voir aussi cette réponse précédente: Accès aux champs privés hérités via la reflection en Java )

getDeclaredFields() vous donne tous les champs de cette classe, y compris les champs private .

getFields() vous donne tous public champs public de cette classe ET ses super-classes.

Si vous voulez private méthodes private / protected de Super Classes, vous devrez appeler à plusieurs resockets getSuperclass() , puis appeler getDeclaredFields() sur l’object Super Class.

Rien ici n’est clairement expliqué dans les javadocs

Voici la méthode que j’utilise pour obtenir tous les champs d’un object

 private  List getFields(T t) { List fields = new ArrayList<>(); Class clazz = t.getClass(); while (clazz != Object.class) { fields.addAll(Arrays.asList(clazz.getDeclaredFields())); clazz = clazz.getSuperclass(); } return fields; } 

essayez ces

Comment lire un champ privé en Java?

Est-il possible en Java d’accéder à des champs privés par reflection

Field.setAccessible (true) est ce que vous devez faire pour le rendre accessible par reflection

 import java.lang.reflect.Field; class B { private int i = 5; } public class A extends B { public static void main(Ssortingng[] args) throws Exception { A a = new A(); Field[] fs = a.getClass().getSuperclass().getDeclaredFields(); for (Field field : fs) { field.setAccessible(true); System.out.println( field.get( a ) ); } } } 

Pour obtenir des champs de superclasses, utilisez getSuperclass() . De là, vous pouvez obtenir des champs de superclasse.

Auparavant demandé.

Accès aux champs privés hérités via la reflection en Java

Dans votre code, définissez field.setAccessible(true);

 ClassName obj = new ClassName(); Field field = ClassName.class.getDeclaredField ("name of the field"); field.setAccessible (true); DataType value = (DataType) field.get (obj); 

Vous devez utiliser setAccessible à true avant d’extraire la valeur. Parfois, JVM ne permet pas d’extraire la variable privée, cela peut donner une exception de sécurité.

Cette solution utilise des stream Java 8, utiles pour ceux qui apprennent la functional programming en Java. Il itère sur getSuperclass et getDeclaredFields selon les autres réponses, mais il le fait de manière fonctionnelle.

La ligne suivante affichera le nom de chaque nom de champ trouvé sur SomeClass ou sur l’une de ses super-classes.

 allFieldsFor(SomeClass.class).map(Field::getName).forEach(System.out::println); 

Voici le code qui parcourt les super-classes pour créer le stream de champs.

 private Stream allFieldsFor( Class c ) { return walkInheritanceTreeFor(c).flatMap( k -> Arrays.stream(k.getDeclaredFields()) ); } private Stream walkInheritanceTreeFor( Class c ) { return iterate( c, k -> Optional.ofNullable(k.getSuperclass()) ); } 

La méthode suivante est modélisée à partir de Streams.iterate, mais Streams.iterate est conçu pour créer des stream infinis. Cette version a été modifiée pour se terminer lorsque Optional.none () est renvoyé par la fonction fetchNextFunction.

 private  Stream iterate( T seed, Function> fetchNextFunction ) { Objects.requireNonNull(fetchNextFunction); Iterator iterator = new Iterator() { private Optional t = Optional.ofNullable(seed); public boolean hasNext() { return t.isPresent(); } public T next() { T v = t.get(); t = fetchNextFunction.apply(v); return v; } }; return StreamSupport.stream( Spliterators.spliteratorUnknownSize( iterator, Spliterator.ORDERED | Spliterator.IMMUTABLE), false ); } 

Oui, c’est possible en utilisant la reflection.

Dans votre code, définissez Field.setAccessible(true);

Allez-y et apprenez le concept mais ne le faites pas 🙂