简体   繁体   English

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

[英]accessing child fields in abstract class throught reflection in java

I have 2 classes: 我有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";
}

And test: 并测试:

public class MainTest {
    public static void main(String[] args) throws IllegalAccessException{
        TestClass test = new TestClass();
        test.showFields();
    }
}

Running this test causes next exception: 运行此测试会导致下一个异常:

java.lang.IllegalAccessException: Class AbstractTestClass can not access a member of class TestClass with modifiers "private"

When i'm debuging code, this contains instance of TestClass. 当我调试代码时,它包含TestClass的实例。

Questions: 问题:

  1. Why does it happen? 为什么会发生?
  2. How to make this code work, not using Field.setAccessible() or changing visibility of fileds? 如何使此代码有效,而不使用Field.setAccessible()或更改文件的可见性?

How to make this code work, not using Field.setAccessible() or changing visibility of fileds? 如何使此代码有效,而不使用Field.setAccessible()或更改文件的可见性?

You can't, you have to make the field accessible to use it 您不能,必须使该字段可访问才能使用它

I believe you are making the same mistake I made when I was starting out: that the abstract class and the extending class are two piece welded together to form a single class with access to all of each others fields and methods etc. 我相信您犯的错误与我刚开始时犯的错误相同:抽象类和扩展类是两部分焊接在一起,形成一个可以访问其他所有字段和方法等的单个类。

Sadly, this is not true: inheritance is a closer relationship that in a normal parent-child object, but access rules must still be obeyed eg if a method is declared protected in the abstract class and the extending class is in a different package, then it cannot be accessed (and vice versa). 令人遗憾的是,这是不正确的:继承与普通父子对象中的关系更为紧密,但是访问规则仍必须遵守,例如,如果在抽象类中声明了方法的protected ,而扩展类在另一个包中,则无法访问它(反之亦然)。

Because the method showFields() is defined in AbstractTestClass , it can only access the fields in that class. 因为方法showFields()是在AbstractTestClass定义的,所以它只能访问该类中的字段。 Fields in TestClass are essentially walled off. TestClass中的字段实际上是隔离的。

The only way around it that I can think of is to override showFields() in TestClass , swallow any exceptions about not being able to access private fields, then call super.showFields() and swallow any exceptions again. 我能想到的唯一解决方法是在TestClass重写showFields() ,吞下有关无法访问私有字段的所有异常,然后调用super.showFields()并再次吞入任何异常。 Not pretty. 不漂亮。

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();
  }
}

I doubt this is what you had in mind... 我怀疑这就是你的想法...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM