是否可以在Java中访问字段之前立即执行代码?

时间:2018-06-22 06:51:56

标签: java reflection field

我正在尝试自动化Java中某些对象的构造。

为此,我有以下示例类:

class TestInjected extends CommonAncestor {

  TestInjected() {
    System.out.println("I am Test Injected");
  }

  void exist() {
    System.out.println("Hey there, I exist");
  }

}

class CommonAncestor {

  CommonAncestor() {
    super();
    init();
  }

  void init() {
    try {
        Field f = this.getClass().getDeclaredField("x");
        f.set(this, f.getType().newInstance());
    } catch (NoSuchFieldException e) {
    } catch (IllegalAccessException e) {
    } catch (InstantiationException e) {
    }
  }

}

public class TestInjection extends CommonAncestor{
  TestInjected x;
  private TestInjected y;

  private TestInjected getY() {
    if (y == null) {
      y = new TestInjected();
    }
    return y;
  }

  public TestInjection() {
    super();
  }

  public void test() {
    x.exist();
  }

  public void test2() {
    getY().exist();
  }

}

我还有一个测试班:

public class TestInjectionTest {

  @Test
  public void test1() {
    TestInjection t = new TestInjection();
    t.test();
    t.test2();
  }
}

我在这里做的是在构造函数上,检查Field x,并通过反射对其进行初始化。这样,我确保无论何时调用方法(如本例中的test()),Field x都已初始化,因此它可以工作。

第二种方法是强制程序员对Field y使用getter,在这种情况下,此getter方法可确保初始化对象。

但是,我想知道,当访问变量时,hava是否有执行反射的方法。可以说,不必以某种方式在构造函数上执行反射代码,而是可以在需要“ x”时执行该代码。

即:

x.exist()

->检查x是否被调用,将其初始化,然后调用exist()

有什么反射方法或任何库给我这个吗?

1 个答案:

答案 0 :(得分:1)

我无法真正理解您要解决的问题,但是我确定有更好的解决方案。使用平台,而不是反对平台。话虽如此,在一般情况下答案是否定的。您可以运行一些重写字节码的操作(本质上是在幕后添加一个吸气剂),但是您不能开箱即用地拦截字段访问。

将字段设为私有,并在需要初始化它们时使用方法公开它们。或者在构造函数中完成。

编辑:根据您的评论,我认为您真正要寻找的是依赖项注入。看一下CDI(https://docs.oracle.com/javaee/6/tutorial/doc/giwhl.html)或Spring(https://spring.io)或Guice(https://github.com/google/guice)。