通过java中的反射访问抽象类中的子字段

时间:2012-06-08 15:49:54

标签: java inheritance reflection field

我有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的实例。

问题:

  1. 为什么会这样?
  2. 如何使此代码工作,而不是使用Field.setAccessible()或更改fileds的可见性?

2 个答案:

答案 0 :(得分:0)

  

如何使此代码工作,而不是使用Field.setAccessible()或更改fileds的可见性?

您不能,您必须使该字段可供使用

答案 1 :(得分:0)

我相信你在我开始时犯了同样的错误:抽象类和扩展类是两个焊接在一起形成一个类,可以访问所有其他字段和方法等。< / p>

可悲的是,事实并非如此:继承是一种在普通父子对象中更接近的关系,但仍必须遵守访问规则,例如:如果方法在抽象类中声明为protected且扩展类在不同的包中,则无法访问它(反之亦然)。

因为方法showFields()是在AbstractTestClass中定义的,所以它只能访问该类中的字段。 TestClass中的字段基本上是隔离的。

我能想到的唯一方法是覆盖showFields()中的TestClass,吞下关于无法访问私有字段的任何例外,然后调用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();
  }
}

我怀疑这是你的想法......