Suppose I have the class
class car
{
int color = 1;
seats carSeats = new seats();
class seats
{
int numSeats = 4;
}
}
Using Java reflection, I can use the following:
car c = new car();
Field[] carFields = c.getClass().getDeclaredFields();
carFields would have { color, carSeats } as the fields. The instance, carSeats, has another field called numSeats.
Technically, I should be able to do another getFields() operation such that:
Field[] seatFields = carFields[1].getClass().getDeclaredFields();
But I am given garbage data (DECLARED, PUBLIC?) Why so? Does Java reflection not work for inner classes?
carFields[1].getClass()
is going to represent a Field
object. You want carFields[1].getType().getDeclaredFields()
.
Also, as BalusC commented, be careful. The fields aren't necessarily in the order you expect.
Here is a short snippet that can give some hints on Reflection
import java.lang.reflect.Field;
public class Car {
int color = 1;
int wheels = 4;
Seats carSeats = new Seats();
class Seats {
int numSeats = 4;
}
public static void printFields(Field[] fields, Object o) {
System.out.println(o.getClass());
try {
for (int i = 0; i < fields.length; i++) {
Field f = fields[i];
f.setAccessible(true);
System.out.println(f.getName() + " " +
f.getType().getName() + " " +
f.get(o));
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
public static void main(String args[]) {
Car car = new Car();
Class<?>[] classes = Car.class.getDeclaredClasses();
printFields(Car.class.getDeclaredFields(), car);
for (int i = 0; i < classes.length; i++) {
Class<?> klass = classes[i];
printFields(klass.getDeclaredFields(), car.carSeats);
}
}
}
I find it good fun to use write code that uses reflection, but really hard to trouble shoot...
You could use Traverser class of java-util library which traverse every field of a class with the support of nested fields, which is what you want.
Traverser - Pass any Java object to this Utility class, it will call your passed in anonymous method for each object it encounters while traversing the complete graph. It handles cycles within the graph. Permits you to perform generalized actions on all objects within an object graph.