Vlad
Vlad

Reputation: 129

Get value of unknown class field

I have bunch of unknown classes that stored in List/Array. How to get the value of fields from these classes?

What should I paste in f.get() ?

for(Class<?> cl : ClassList){
        for(Field f : cl.getFields()){
            try {
                f.setAccessible(true);
                writeln(f.get( <WHAT TO PASTE HERE> ));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

Upvotes: 1

Views: 4391

Answers (2)

MarcelK
MarcelK

Reputation: 283

As far as reflection is concerned, I prefer to rely on frameworks with more readable API then the standard Java Reflection API. I've used two:

The first one is Mirror. Getting fields values (either static or instance) looks like this:

Getting value of a static field:

Class clazz;
Object value = new Mirror().on(clazz).get().field("fieldName");

Getting value of a instance field:

Object target;
Object value = new Mirror().on(target).get().field("fieldName");

You can also pass a java.lang.reflect.Field instead of fieldName String.

Getting value of a static field:

Field aField;
Class clazz;
Object value = new Mirror().on(clazz).get().field(aField);

FEST-Reflect is a another nice library (FEST fluent Assertions are really nice, BTW).

import static org.fest.reflect.core.Reflection.*;

// Retrieves the value of the field "name"
String name = field("name").ofType(String.class).in(person).get();

// Retrieves the value of the field "powers"
List<String> powers = field("powers").ofType(new TypeRef<List<String>>() {})
                                     .in(jedi).get();

// Retrieves the value of the static field "count" in Person.class
int count = field("count").ofType(int.class).in(Person.class).get();


// Retrieves the value of the static field "commonPowers" in Jedi.class
List<String> commmonPowers = field("commonPowers")
                                    .ofType(new TypeRef<List<String>>() {})
                                    .in(Jedi.class).get();

All examples taken from the respective library's documentation.

Some quick and rough examples based on the code you've provided: To achieve what you want (If I understand correctly) with Mirror:

for(Class<?> cl : classList){
   Mirror mirror = new Mirror().on(cl);
   for(Field f: mirror.reflectAll().fields()) {
      if(java.lang.reflect.Modifier.isStatic(f.getModifiers()) {
         writeln(mirror.get().field(f));
      }
   }
}

I've assumed that you want to read only static fields. For an Object list:

for(Object obj : objectList){
   for(Field f: new Mirror().on(obj.getClass()).reflectAll().fields()) {
       writeln(new Mirror().on(obj).get().field(f));
   }
}

The same with FEST-Reflect:

for(Class<?> cl : classList){
    for(Field f : cl.getFields()){
      if(java.lang.reflect.Modifier.isStatic(f.getModifiers()) {
         writeln(field(f.getName()).ofType(f.getType()).in(cl).get());
      }
    }
}

and:

for(Object obj : objectList){
   for(Field f: obj.getClass().getFields()) {
      if(!java.lang.reflect.Modifier.isStatic(f.getModifiers()) { //not 100% sure if this is required
         writeln(field(f.getName()).ofType(f.getType()).in(obj).get());
      }
   }
}

Note that you can't read instance filed values without an actual class instance (object) to read them from.

I hope this helps. The examples could use some refactoring, of course.

Upvotes: 4

tbodt
tbodt

Reputation: 16987

The field that you have only points to a field, not to a particular field in a particular object, and you must have an object to get the field value from. The argument must be the object to extract the field value from. If the object is of the wrong type, an IllegalArgumentException is thrown. So be careful about that. Here's a snippet to illustrate:

Field field = Integer.class.getDeclaredField("value"); // I think that's the field name
int val = field.get(new Integer(8)); // returns 8
int val2 = field.get("Hello"); // throws IllegalArgumentException

Upvotes: 1

Related Questions