0

How can I iterate over the attributes of an object, with the attribute names provided in a list/array - NOT all attributes, like using reflection & getDeclaredFields().

public class MyClass
{
    public type1 att1;
    public type2 att2;
    public type3 att3;

    public MyClass(
        att1="helo";
        att2="bye";
        att3="morning";
    );

    ...
    public void function()
    {
        String myStrings[];
        myStrings = new String[] { "att2", "att3" };

        MyClass myobject = new MyClass();
        for(var in myStrings)
        {
           System.out.println(var);
           System.out.println(myobject.var);
           System.out.println();
        }
    }
}
vsminkov
  • 10,912
  • 2
  • 38
  • 50
user3616725
  • 3,485
  • 1
  • 18
  • 27

2 Answers2

1

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

vempo
  • 3,093
  • 1
  • 14
  • 16
  • indeed `MyClass.class.getDeclaredField(var);` is what I was after. Could you elaborate on "handle exception associated with the reflection calls." - do you mean if my field name does not exist, or something else? – user3616725 Aug 15 '16 at 07:41
0

You probably want to use some technology that builds on top of JavaBeans / BeanInfo. Apache Commons / BeanUtils is a good starting point here.

Please refer to this previous answer of mine for more info: https://stackoverflow.com/a/5856982/342852

But if you just want to use fields, not bean properties, here's a Java 8 method to do so:

public static Map<String, Object> getFieldProperties(Object o, Collection<String> fields) {
  Class<?> type = o.getClass();
  return fields.stream().map(n -> {
    try {
      return type.getDeclaredField(n);
    } catch (NoSuchFieldException e) {
      throw new IllegalStateException(e);
    }
  }).collect(Collectors
    .toMap(
      (Function<Field, String>) Field::getName,
      (Function<Field, Object>) field -> {
        try {
          field.setAccessible(true);
          return field.get(o);
        } catch (IllegalAccessException e) {
          throw new IllegalStateException(e);
        }
    }));
}

Unfortunately the checked exceptions make this more verbose than it would need to be.

Community
  • 1
  • 1
Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588