Java reflection: Find fields of a subclass

一笑奈何 提交于 2020-01-13 10:35:10

问题


I have a class hierarchy like so: (=> means "is a subclass of")

anonymous instance class => abstract class => generic abstract class

or more succinctly:

C => B => A

When executing, "C" calls one of "A"'s methods. Within that method in "A", I want to use reflection to find protected fields of the object that are defined in class "B". (So these are fields that "C" and "B" can see, but not "A".)

How would I do this with Java reflection? And how can I future-proof it in case I add something between A & B or B & C?


回答1:


You have to use getDeclaredFields() repeatedly on each class in the inheritance hierarchy of your object's class (via getSuperclass()).

However, what you are planning sounds like a nasty violation of the concept of inheritance. The best way of future-proofing would be to avoid this kind of thing entirely. What are you trying to do that you think requires such reflection shenanigans?




回答2:


As far as I know, there is no way to know about your "child classes" in Java reflectively. Wouldn't a better solution be to create an abstract method on A that B would have to implement, and call that instead?

public class A {
   //other stuff here
   protected void abstract mySubMethod();
   //other stuff here
}

Edit: If I have misunderstood your question, and you actually want to know about parent classes, then yes: getDeclaredFields() is the correct reflective method to use, as mentioned by other posters.

Additional Edit: I hate to keep modifying this answer, but... In general, if you are attempting to give access to a parent class, the "correct" and "future proof" way to do this is to create abstract methods that are getters or setters (or even more complex, if necessary) and then have the children honor those or not, and respond as appropriate.

That being said, you can do something like the others have said:

getClass().getParentClass().getDeclaredFields()

However, that would only work if C is always directly inherited from B. Reflections is, by it's very nature, tricky and specific. I have to do a LOT of it on a project I am on (don't ask, trust me, you DON'T want to know), and I avoid it whenever possible. Unless there is a good reason for A to need the protected fields and it is discovering information about them, then you would likely want to use an abstract method. I would also submit that it is likely that you can solve the other problem with an abstract method, however it might be a little bit harder.




回答3:


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

And then iterate those fields and get the ones you want.

In case your hierarchy grows, you can transform the above to a recursive calls to getSuperclass() (while getSuperclass() != Object.class), thus collecting all fields of all superclasses.




回答4:


Example of recursive method for java 8+

static final Field[] getDeclaredFields(Class clazz) {
    final Field[] fields = clazz.getDeclaredFields();

    if ( clazz.getSuperclass() != Object.class ) {
        final Field[] pFields = getDeclaredFields(clazz.getSuperclass());
        final Field[] allFields = new Field[fields.length + pFields.length];
        Arrays.setAll(allFields, i -> (i < pFields.length ? pFields[i] : fields[i - pFields.length]));
        return allFields;
    } else
        return fields;
}


来源:https://stackoverflow.com/questions/2172263/java-reflection-find-fields-of-a-subclass

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!