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

标签 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() 或更改文件可见性的情况下使此代码正常工作?

最佳答案

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

遗憾的是,这不是真的:继承是一种比普通父子对象更紧密的关系,但仍然必须遵守访问规则,例如如果一个方法在抽象类中被声明为 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/

相关文章:

c# - 检测对象的类型是否为 .NET Framework 定义的类型

java - Java 类的公共(public)父类(super class)型

java - 提取指定单词之后的所有单词直到句子结尾

java - 在 Java 中,新的总是新的吗?

java - 在 Java 中编写 for 循环有更短的方法吗?

java - 在@Transactional注释中设置默认事务管理器?

c# - 一种将基类型转换为派生类型的方法

调用 Swift 协议(protocol)扩展方法而不是子类中实现的方法

c# - 访问基类重写 ToString 方法中的子类对象

c# - 如何为特定接口(interface)类型注册DI服务?