我有一种情况,我总是需要运行一些依赖于对象本身的代码
public abstract class A{
public A(X x){
//init A stuff
x.getAList("stuff").add(this);
x.getAList("otherstuff").add(this);
}
}
public class B extends A{
public B(X x){
super(x);
//init B stuff
}
}
public class C extends A{
public C(X x){
super(x);
//init C stuff
x.getAList("otherstuff").remove(this);
x.getAList("morestuff").add(this);
}
}
public class SomeClass{
private X someX;
public A somefunc(boolean b){
if(b){
return new B(someX);
}else{
return new C(someX);
}
}
}
问题如下。在此示例中,我在构造函数中使用了 this
。如果另一个线程试图通过 someX.getAList 访问该对象,则可能导致该线程在构造函数结束之前访问该对象。
您可以通过 somefunc 将对象添加到 AList
public class SomeClass{
private X someX;
public A somefunc(boolean b){
A a;
if(b){
a = new B(someX);
someX.getAList("stuff").add(a);
someX.getAList("otherstuff").add(a);
}else{
a = new C(someX);
someX.getAList("stuff").add(a);
someX.getAList("morestuff").add(a);
}
return a;
}
}
问题是 B 和 C 也可以在别处实例化,并且每次创建 B 或 C 时都需要以指定的方式添加它们。我不想将对象添加到 AList 是用户的责任,而是类的责任。我也不希望用户必须调用为他们执行此操作的 init 函数。另一方面,我不希望出现任何并发问题。
有没有一种方法或模式可以实现这一点?
Golang 有类似 defer 的东西,可以让你在函数/方法/构造函数完成后运行一段代码。
最佳答案
改为为父类(super class)和子类创建一个工厂方法,并将构造函数设为私有(private),迫使每个想要实例的人都使用工厂方法。工厂方法是一种返回完全构造的实例的方法。一旦实例完全构建(在工厂方法中调用构造函数之后),将实例添加到列表中,这样就没有线程可以获取不完整/未完成的实例。
工厂方法的要点是将所有初始化代码与任何非初始化代码严格隔离,以避免访问和暴露未初始化的字段。它还可以作为用户的选择器,自动返回合适的(子)类型,无需指定。( Interesting design-patterns )
abstract class A{
protected A(){
//constructor code goes here
}
public void afterFinalisation(final X x) {
x.getAList("stuff").add(this);
x.getAList("otherstuff").add(this);
}
}
class B extends A{
protected B(){
super();
//constructor code goes here
}
public static B create(final X x) {
final B returnValue = new B();
returnValue.afterFinalisation(x);
return returnValue;
}
}
class C extends A{
protected C(){
super();
//constructor code goes here
}
@Override
public void afterFinalisation(final X x) {
super.afterFinalisation(x);
x.getAList("otherstuff").remove(this);
x.getAList("morestuff").add(this);
}
public static C create(final X x) {
final C returnValue = new C();
returnValue.afterFinalisation(x);
return returnValue;
}
}
class SomeClass{
private final X someX = new X();
public A somefunc(final boolean b){
if(b){
return B.create(this.someX);
}else{
return C.create(this.someX);
}
}
}
构造函数代码归功于 coolcats iteration of my answer ,我试图避免将代码放入 protected 构造函数中,而是使用 init() 方法,这需要对最终字段进行大量不优雅的解决方法。
关于java - 在 Java 中总是在构造函数之后执行方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37380704/