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/