有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java反射:查找子类的字段

我有这样一个类层次结构:(=>;表示“是的子类”)

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

或者更简洁地说:

C => B => A

执行时,“C”调用“A”的方法之一。在“A”中的方法中,我想使用反射来查找在类“B”中定义的对象的受保护字段。(所以这些字段是“C”和“B”可以看到的,但不是“A”。)

如何使用Java反射来实现这一点?如果我在A&;之间添加了一些东西,我如何证明它的未来;B或B&;C


共 (4) 个答案

  1. # 1 楼答案

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

    然后迭代这些字段,得到你想要的

    在层次结构增长的情况下,您可以将上述内容转换为对getSuperclass()(而getSuperclass() != Object.class)的递归调用,从而收集所有超类的所有字段

  2. # 2 楼答案

    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;
    }
    
  3. # 3 楼答案

    据我所知,没有办法了解Java中的“子类”。更好的解决方案不是在a上创建一个B必须实现的抽象方法,然后调用它吗

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

    编辑: 如果我误解了你的问题,而你真的想了解父类,那么是的:getDeclaredFields()是正确的反射方法,正如其他海报所提到的

    附加编辑: 我不想一直修改这个答案,但是。。。 一般来说,如果您试图授予对父类的访问权,“正确”和“未来证明”的方法是创建抽象方法,这些方法是getter或setter(或者更复杂,如果必要的话),然后让孩子们尊重或不尊重这些方法,并根据需要做出响应

    话虽如此,你可以像其他人所说的那样:

    getClass().getParentClass().getDeclaredFields()
    

    然而,只有在C总是直接从B继承的情况下,这才有效。反射从本质上来说是复杂而具体的。我必须在一个我正在做的项目上做很多(不要问,相信我,你不想知道),我会尽可能避免。除非有充分的理由让a需要受保护的字段,并且它正在发现有关这些字段的信息,否则您可能希望使用抽象方法。我还想说的是,你很可能可以用一个抽象的方法解决另一个问题,不过这可能有点难

  4. # 4 楼答案

    必须在对象类的继承层次结构中的每个类上重复使用^{}(通过^{}

    然而,你的计划听起来像是对继承概念的严重违反。最好的未来证明方法是完全避免这种事情。你想做什么你认为需要这种反省的恶作剧