java - 使用 final 字段防止 "this"在构造过程中转义

标签 java constructor dependency-injection

public class App {
    private final A a;
    private final Server server; 
    public App(){
        a = new A(this); //Bad, this is escaping before it's initialized.
    }
    @Subscribe //This event fires some time after App is finished constructing.
    public void registerStuff(RegisterEvent event){
        server = event.getServer(); //Not possible due to final field and this not being the constructor, is there such thing as a lazy final?
        a.register();
    }
}

public class A {
    private final App app;
    private final BuilderSpec spec;
    public A(App app){
        this.app = app;
        this.spec = app.getServer().builder(this.app).build();
    }
    public void register(){
        app.getServer().doStuff(this.app, this.spec);
    }
}

我已经阅读了一些关于“this”转义是什么的内容,并意识到之前的代码很糟糕,因为我不知道外部进程正在使用 this 引用做什么,所以它不应该传递到外部构造函数,直到它被构造。

但是,由于 App 和 A 中都有 final 字段,我真的看不出我之后如何初始化它,或者懒惰地初始化它。使字段 final 比 this 转义更不重要吗?我不确定。

最佳答案

如果构造函数依赖被循环,它们可能会成为一个问题。大多数 IoC 容器都使用构建后方法来避免对象实例化问题。

将主体应用到您的代码中,它看起来像

class App {
    private A a;
    public App() { 
      // not necessary to have, just to show that we have no logic inside 
    }
    protected void init() {  // choose access modifiers
        // init something in App;
        a = new A(this);  // safe to pass this now.           
    }
}

class A {
   private final App app;

   public A(App app) {
      this.app = app;
      // do whatever you need
      // if logic affects other components, create init() method here
   }      
}

是的,应用程序中的引用不是最终的。但这种设计更自然,更不容易出错。

关于java - 使用 final 字段防止 "this"在构造过程中转义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30806331/

相关文章:

java - 未找到 Mysql 表

java - 将 Artifact 部署到两个不同的远程存储库 - Maven?

C++ : operator new and default constructor

c++ - 在构造函数中初始化指针的正确方法

c++ - 如果只有一个成员没有默认构造函数,为什么 union 有一个已删除的默认构造函数?

zend-framework - 如何在 SOA 中使用依赖注入(inject)?

java - 如何使用 yourkit 调查类加载器泄漏

java - Java 中的 while (x = false) 和 while (!x) 有什么区别?

c# - 使用静态工厂是依赖注入(inject)的有效模式吗?

php - 依赖注入(inject) : pulling required components when they are actually needed