How to iterate over class attributes in Java?

How can I loop around class attributes in Java dynamically.

For example:

public class MyClass{ private type1 att1; private type2 att2; ... public void function(){ for(var in MyClass.Attributes){ System.out.println(var.class); } } } 

is this possible in java?

+66
java loops attributes
Jul 26 '10 at 10:25
source share
7 answers

There is no linguistic support to do what you ask.

You can reflect type elements at runtime using reflection (e.g. Class.getDeclaredFields() to get a Field array), but depending on what you are trying to do, this might not be the best solution.

see also

Related Questions

  • What is reflection and why is it useful?
  • Java Reflection: why is it so bad?
  • How can reflection lead to code smells?
  • Reset properties of java objects



Example

Here is a simple example to show only what reflections can do.

 import java.lang.reflect.*; public class DumpFields { public static void main(String[] args) { inspect(String.class); } static <T> void inspect(Class<T> 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.toString(field.getModifiers()), field.getType().getSimpleName(), field.getName() ); } } } 

The snippet above uses reflection to validate all declared fields of class String ; he produces the following conclusion:

 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 



Effective Java 2nd Edition, paragraph 53: Preferred interfaces for reflection

These are excerpts from the book:

Given the Class object, you can get Constructor , Method and Field instances representing the constructors, methods, and fields of the class. [They] allow you to reflexively manipulate their basic counterparts. This power, however, comes at a price:

  • You are losing all the benefits of compile time checking.
  • The code required to provide reflective access is inconvenient and detailed.
  • Performance.

Typically, objects should not pay attention to regular applications at run time.

There are several complex applications that require reflection. Examples include [... omitted specifically ...] If you have any doubts as to whether your application falls into one of these categories, this probably does not.

+84
Jul 26 '10 at 10:28
source share
β€” -

Accessing fields directly is not a very good style in java. I would suggest creating getter and setter methods for your bean fields, and then use the Introspector and BeanInfo classes from the java.beans package.

 MyBean bean = new MyBean(); BeanInfo beanInfo = Introspector.getBeanInfo(MyBean.class); for (PropertyDescriptor propertyDesc : beanInfo.getPropertyDescriptors()) { String propertyName = propertyDesc.getName(); Object value = propertyDesc.getReadMethod().invoke(bean); } 
+39
Jul 26 '10 at 11:03
source share

So far, I agree with JΓΆrn's answer, if your class complies with the JavaBeabs specification, here is a good alternative if it is not, and you use Spring.

Spring has a class called ReflectionUtils that offers some very powerful features, including doWithFields (class, callback) , a visitor style method that allows you to iterate over class fields using a callback object as follows:

 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)); }); } 

But here's a warning: the class is marked as "for internal use only", which is a pity if you ask me

+16
Jul 26 '10 at 11:28
source share

A simple way to iterate over class fields and get values ​​from an object:

  Class<?> c = obj.getClass(); Field[] fields = c.getDeclaredFields(); Map<String, Object> temp = new HashMap<String, Object>(); for( Field field : fields ){ try { temp.put(field.getName().toString(), field.get(obj)); } catch (IllegalArgumentException e1) { } catch (IllegalAccessException e1) { } } 
+10
Jan 01 '13 at 20:52
source share

Java has Reflection (java.reflection. *), But I would suggest looking into a library like Apache Beanutils, this will make the process much less hairy than direct reflection.

+6
Jul 26 '10 at 10:26
source share

You can cyclically combine class attributes with the java Reflections API -

 for (Field field : objClass.getDeclaredFields()) { // Invoke the getter method on the Institution1 object. Object objField = new PropertyDescriptor(field.getName(), Institute1.class).getReadMethod().invoke(inst1); 
+2
Jun 23 '16 at 19:31
source share

Here is a solution that sorts properties in alphabetical order and prints them all together with their values:

 public void logProperties() throws IllegalArgumentException, IllegalAccessException { Class<?> aClass = this.getClass(); Field[] declaredFields = aClass.getDeclaredFields(); Map<String, String> logEntries = 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<String> sortedLog = new TreeSet<>(logEntries.keySet()); StringBuilder sb = new StringBuilder("Class properties:"); Iterator<String> it = sortedLog.iterator(); while (it.hasNext()) { String key = it.next(); sb.append(logEntries.get(key)); } System.out.println(sb.toString()); } 
0
Jun 10 '14 at 23:34
source share



All Articles