如何获得扩展类的非静态字段?
我知道如何获取静态字段,但不知道如何从实例获取字段。
我已经尝试了
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;
}
}
我需要从外部类中获取名称。
答案 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);