Comment puis-je effectuer une boucle sur une classe d’atsortingbuts dans Java dynamicment.
Pour par exemple:
public class MyClass { private type1 att1; private type2 att2; ... public void function() { for(var in MyClass.Atsortingbutes) { System.out.println(var.class); } } }
est-ce possible en Java?
Il n’y a pas de support linguistique pour faire ce que vous demandez.
Vous pouvez accéder de manière réfléchie aux membres d’un type lors de l’exécution en utilisant la reflection (par exemple, avec Class.getDeclaredFields()
pour obtenir un tableau de Field
), mais en fonction de ce que vous essayez de faire, cette solution n’est peut-être pas la meilleure.
Voici un exemple simple pour montrer seulement une partie de ce que la reflection est capable de faire.
import java.lang.reflect.*; public class DumpFields { public static void main(Ssortingng[] args) { inspect(Ssortingng.class); } static void inspect(Class klazz) { Field[] fields = klazz.getDeclaredFields(); System.out.printf("%d fields:%n", fields.length); for (Field field : fields) { System.out.printf("%s %s %s%n", Modifier.toSsortingng(field.getModifiers()), field.getType().getSimpleName(), field.getName() ); } } }
L’extrait de code ci-dessus utilise la reflection pour inspecter tous les champs déclarés de la class Ssortingng
; il produit la sortie suivante:
7 fields: private final char[] value private final int offset private final int count private int hash private static final long serialVersionUID private static final ObjectStreamField[] serialPersistentFields public static final Comparator CASE_INSENSITIVE_ORDER
Ce sont des extraits du livre:
Étant donné un object
Class
, vous pouvez obtenir des instances deConstructor
, deMethod
et deField
représentant les constructeurs, les méthodes et les champs de la classe. [Ils] vous permettent de manipuler leurs homologues sous-jacents de manière réfléchie . Ce pouvoir a cependant un prix:
- Vous perdez tous les avantages de la vérification au moment de la compilation.
- Le code requirejs pour effectuer un access réflexif est maladroit et verbeux.
- La performance en souffre.
En règle générale, les objects ne doivent pas être accessibles de manière réfléchie dans les applications normales au moment de l’exécution.
Il existe quelques applications sophistiquées qui nécessitent une reflection. Les exemples incluent [… omis à dessein …] Si vous avez des doutes quant à savoir si votre application appartient à l’une de ces catégories, ce n’est probablement pas le cas.
L’access aux champs directement n’est pas vraiment un bon style en Java. Je suggère de créer des méthodes getter et setter pour les champs de votre bean, puis d’utiliser les classes Introspector et BeanInfo du package java.beans.
MyBean bean = new MyBean(); BeanInfo beanInfo = Introspector.getBeanInfo(MyBean.class); for (PropertyDescriptor propertyDesc : beanInfo.getPropertyDescriptors()) { Ssortingng propertyName = propertyDesc.getName(); Object value = propertyDesc.getReadMethod().invoke(bean); }
Bien que je sois d’accord avec la réponse de Jörn si votre classe est conforme à la spécification JavaBeabs, voici une bonne alternative si ce n’est pas le cas et que vous utilisez Spring.
Spring a une classe nommée ReflectionUtils qui offre des fonctionnalités très puissantes, y compris doWithFields (class, callback) , une méthode de style visiteur qui vous permet de parcourir des champs de classes en utilisant un object de rappel comme celui-ci:
public void analyze(Object obj){ ReflectionUtils.doWithFields(obj.getClass(), field -> { System.out.println("Field name: " + field.getName()); field.setAccessible(true); System.out.println("Field value: "+ field.get(obj)); }); }
Mais voici un avertissement: la classe est étiquetée comme “à usage interne seulement”, ce qui est dommage si vous me demandez
Un moyen simple d’itérer sur les champs de classe et d’obtenir des valeurs à partir de l’object:
Class> c = obj.getClass(); Field[] fields = c.getDeclaredFields(); Map temp = new HashMap(); for( Field field : fields ){ try { temp.put(field.getName().toSsortingng(), field.get(obj)); } catch (IllegalArgumentException e1) { } catch (IllegalAccessException e1) { } }
Java a Reflection (java.reflection. *), Mais je suggère de regarder dans une bibliothèque comme Apache Beanutils, cela rendrait le processus beaucoup moins poilu que d’utiliser directement la reflection.
Vous pouvez boucler dynamicment les atsortingbuts de classe en utilisant l’API Java Reflections
for (Field field : objClass.getDeclaredFields()) { // Invoke the getter method on the Institution1 object. Object objField = new PropertyDescriptor(field.getName(), Institute1.class).getReadMethod().invoke(inst1);
Voici une solution qui sortinge les propriétés par ordre alphabétique et les affiche avec leurs valeurs:
public void logProperties() throws IllegalArgumentException, IllegalAccessException { Class> aClass = this.getClass(); Field[] declaredFields = aClass.getDeclaredFields(); Map logEnsortinges = new HashMap<>(); for (Field field : declaredFields) { field.setAccessible(true); Object[] arguments = new Object[]{ field.getName(), field.getType().getSimpleName(), String.valueOf(field.get(this)) }; String template = "- Property: {0} (Type: {1}, Value: {2})"; String logMessage = System.getProperty("line.separator") + MessageFormat.format(template, arguments); logEntries.put(field.getName(), logMessage); } SortedSet sortedLog = new TreeSet<>(logEntries.keySet()); StringBuilder sb = new StringBuilder("Class properties:"); Iterator it = sortedLog.iterator(); while (it.hasNext()) { Ssortingng key = it.next(); sb.append(logEnsortinges.get(key)); } System.out.println(sb.toSsortingng()); }