我有 2 个类:
public abstract class AbstractTestClass {
private String abstractString = "abstract";
public void showFields() throws IllegalAccessException{
for (Field field : this.getClass().getDeclaredFields()) {
System.out.println(field.get(this));
}
}
}
public class TestClass extends AbstractTestClass {
private String concreteString = "concreteString";
}
然后测试:
public class MainTest {
public static void main(String[] args) throws IllegalAccessException{
TestClass test = new TestClass();
test.showFields();
}
}
运行这个测试会导致下一个异常:
java.lang.IllegalAccessException: Class AbstractTestClass can not access a member of class TestClass with modifiers "private"
当我调试代码时,它包含 TestClass 的实例。
问题:
- 为什么会这样?
- 如何在不使用 Field.setAccessible() 或更改文件可见性的情况下使此代码正常工作?
最佳答案
我相信你犯了我刚开始时犯的同样的错误:抽象类和扩展类是两部分焊接在一起形成一个类,可以访问所有其他字段和方法等。
遗憾的是,这不是真的:继承是一种比普通父子对象更紧密的关系,但仍然必须遵守访问规则,例如如果一个方法在抽象类中被声明为 protected
而扩展类在不同的包中,那么它就不能被访问(反之亦然)。
因为 showFields()
方法定义在 AbstractTestClass
中,它只能访问该类中的字段。 TestClass
中的字段基本上被隔离了。
我能想到的唯一解决方法是重写 TestClass
中的 showFields()
,吞下任何关于无法访问私有(private)字段的异常,然后调用super.showFields()
并再次吞下任何异常。不漂亮。
public abstract class AbstractTest {
private String abstractString = "abstract";
public void showFields() throws IllegalAccessException {
for (Field field : this.getClass().getSuperclass().getDeclaredFields()) {
try {
System.out.println(field.get(this));
}
catch (IllegalAccessException e) {
// swallow
}
}
}
}
public class MyTest extends AbstractTest
{
private String concreteString = "concreteString";
@Override public void showFields() throws IllegalAccessException {
for (Field field : this.getClass().getDeclaredFields()) {
try {
System.out.println(field.get(this));
}
catch (IllegalAccessException e) {
// swallow
}
}
super.showFields();
}
}
我怀疑这是你的想法......
关于java - 通过java中的反射访问抽象类中的子字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10952098/