How to Loop Over a Class Attributes in Java

How to loop over a Class attributes in Java?

There is no linguistic support to do what you're asking for.

You can reflectively access the members of a type at run-time using reflection (e.g. with Class.getDeclaredFields() to get an array of Field), but depending on what you're trying to do, this may not be the best solution.

See also

  • Java Tutorials: Reflection API / Advanced Language Topics: Reflection

Related questions

  • What is reflection, and why is it useful?
  • Java Reflection: Why is it so bad?
  • How could Reflection not lead to code smells?
  • Dumping a java object’s properties


Example

Here's a simple example to show only some of what reflection is capable of doing.

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 above snippet uses reflection to inspect all the declared fields of class String; it produces the following output:

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, Item 53: Prefer interfaces to reflection

These are excerpts from the book:

Given a Class object, you can obtain Constructor, Method, and Field instances representing the constructors, methods and fields of the class. [They] let you manipulate their underlying counterparts reflectively. This power, however, comes at a price:

  • You lose all the benefits of compile-time checking.
  • The code required to perform reflective access is clumsy and verbose.
  • Performance suffers.

As a rule, objects should not be accessed reflectively in normal applications at runtime.

There are a few sophisticated applications that require reflection. Examples include [...omitted on purpose...] If you have any doubts as to whether your application falls into one of these categories, it probably doesn't.

How to loop over a Class attributes in Java - from a given list (NOT reflection getDeclaredFields())?

Your question is somewhat ambiguous about using reflection. If you are OK with reflection, but want specific fields only without iterating over getDeclaredFields(), then the following code should work for you:

for (String var : myStrings) {
Field field = MyClass.class.getDeclaredField(var);
field.setAccessible(true);
System.out.println(var);
System.out.println(field.get(myObject));
System.out.println();
}

Note that this code works for private fields, too. Also, keep in mind that you'll have to handle exception associated with the reflection calls.

UPDATE: Exceptions thrown in this code.

MyClass.class.getDeclaredField(var) declares a checked NoSuchFieldException. You must handle it because obviously there is no mechanism to make sure that the fields in myString match an actual implementation of MyClass.

field.get(myObject) throws a checked IllegalAccessException if the field is inaccessible. Which it should not be because of field.setAccessible(true), but you still have to catch or re-throw the exception.

There are also unchecked exceptions you may want to handle. See the javadoc for details

  • java.lang.Class.getDeclaredField(String)
  • java.lang.reflect.AccessibleObject.setAccessible(boolean) inherited by java.lang.reflect.Field
  • java.lang.reflect.Field.get(Object)

Iterate over object attributes in java

Class cls = Class.forName("Foo");
Field[] fields = cls.getDeclaredFields();

Should return all the declared fields for the class using reflection.
More info @ http://java.sun.com/developer/technicalArticles/ALT/Reflection/

How do I iterate over class members?

Yes, you do need reflection. It would go something like this:

public static void getObject(Object obj) {
for (Field field : obj.getClass().getDeclaredFields()) {
//field.setAccessible(true); // if you want to modify private fields
System.out.println(field.getName()
+ " - " + field.getType()
+ " - " + field.get(obj));
}
}

(As pointed out by ceving, the method should now be declared as void since it does not return anything, and as static since it does not use any instance variables or methods.)

See the reflection tutorial for more.

Loop through an object and get the value from all its variables

You can use reflection to do this:

Field[] fields = games.getClass().getDeclaredFields();

for(Field field: fields) {
//do stuff
}

getDeclaredFields():

Returns an array of Field objects reflecting all the fields declared by the class or interface represented by this Class object. This includes public, protected, default (package) access, and private fields, but excludes inherited fields.

Java iterate over class fields to create other class

This is something you can do easily with reflection. In the example below, I renamed class Test to Property because it represents a key-value pair. If you are happy with using whatever toString() returns as the value for a field, then the solution is pretty simple:

public class Property {
private final String name;
private final String value;

public Property(String name, String value) {
this.name = name;
this.value = value;
}

public static List<Property> toProperties(Object object, String... fieldNames)
throws ReflectiveOperationException
{
ArrayList<Property> properties = new ArrayList<>();
for( String fieldName : fieldNames ) {
Field field = object.getClass().getDeclaredField(fieldName);
properties.add(new Property(fieldName, field.get(object).toString()));
}
return properties;
}

public String toString() {
return String.format("%s: \"%s\"", name, value);
}
}

This sample requires you to specify the names of the desired fields explicitly, for example:

List<Property> properties = Property.toProperties(myExample, "a", "b", "c");

If you'd rather have the fields be auto-detected based on some criterion (for example all primitive and String-typed fields, then you could add this logic within toProperties and get rid of the varargs.



Related Topics



Leave a reply



Submit