2

I have the following generic function that I would like to use from multiple classes. The problem is that if I call this from a helper class I cannot obtain the field objects because of the visibility.

public <T> List<T> descendingServices(Class<T> cls) {
  List<T> descendings = new ArrayList<>();

  for (Field field : EnvironmentServiceImpl.class.getDeclaredFields()) {
    Object obj;
    try {
      obj = field.get(this);
      if (cls.isInstance(obj)) {
        T descending = (T) obj;
        descendings.add(descending);
      }
    } catch (IllegalAccessException e) {
    }
  }

  return descendings;
}

Can i somehow workaround this without using setAccessible on the field?

gsf
  • 6,612
  • 7
  • 35
  • 64
  • nope. you can set accessible twice, though Edit: looks like you get a new object, so you don't even have to revert it – dev_feed Dec 12 '17 at 19:02
  • see: https://stackoverflow.com/questions/10638826/java-reflection-impact-of-setaccessibletrue – dev_feed Dec 12 '17 at 19:03

1 Answers1

1

The solution would be to think about how you would access the field if you weren't using reflection first. Then you can add the reflection code after you've figured out how to access the data.

If you can't access the field because it's not public, then the class that declared the field should declare a public getter method that accesses the field for you, providing encapsulation for itself.

Add getter methods to the class if necessary. Then call Class's getMethods method instead of getDeclaredFields. You may need to bypass other methods that you don't want to process.

From the Javadocs for getMethods:

Returns an array containing Method objects reflecting all the public methods of the class or interface represented by this Class object, including those declared by the class or interface and those inherited from superclasses and superinterfaces.

rgettman
  • 176,041
  • 30
  • 275
  • 357