使用反射获取非静态继承字段

时间:2017-10-06 19:34:22

标签: java reflection

如何获得扩展类的非静态字段

我知道如何获取静态字段,但不知道如何从实例获取字段

我已经尝试了

Field commandName = command.getField("name");

但我得到NoSuchFieldException 例外

这些是类:

public class A extends B{

    public A(String name){
        super(name);
    }
}

public class B{
    private String name;
    protected B(String name){
        this.name = name;
    }
}

我需要从外部类中获取名称。

2 个答案:

答案 0 :(得分:2)

使用类Test,因此:

public class Test {

    public int field1;

}

一个子类SubTest,如下:

//This class extends Test
public class SubTest extends Test  {

    public SubTest(int value) {
        field1 = value;//field1 is public, so we can access it from subclass.
    }

}

我们可以使用Field对象执行以下操作:

public static void main(String[] args)
            throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
        SubTest t0 = new SubTest(-10), t1 = new SubTest(0), t2 = new SubTest(10);

        Field f = SubTest.class.getField("field1");
        System.out.println(f.get(t0));
        System.out.println(f.get(t1));
        System.out.println(f.get(t2));

    }

打印:

-10
0
10

解释:Java中的Field类可以从Class对象(不是类的实例)获取,可用于操作/读取实际它表示对象的字段。在此示例中,我们获得了代表Field的{​​{1}}类,然后我们使用它来从我们创建的每个field1中获取实际字段的值。

请注意main方法抛出的异常。 Java反射有时会抛出许多已检查的异常。

如果超类(SubTest)中的字段为Test,则需要获取类的超类(即private的超类)然后获取宣布字段。有关更多信息,请参阅Zabuza指出的this link

答案 1 :(得分:1)

使用反射API

可以从myObject.getClass() myObject.getClass().getDeclaredFields()访问这些方法。

以下是Class的{​​{3}}。

请注意,方法Class#getField也会搜索对象的超类documentation)。但正如文档中明确指出的那样,此方法仅搜索公共成员

在您的具体示例中,您尝试访问超类私有成员。为此,您首先需要获得对该超类的引用并使字段公开,否则您无法访问它。之后,您可以使用所述方法访问该字段:

A a = new A("foo");

// Make name public
Field nameField = a.getClass().getSuperClass().getDeclaredField("name");
nameField.setAccessible(true);

// Access the name
String name = (String) nameField.get(a);