在 java 的 super 调用之前创建一个对象

问题描述 投票:0回答:3

考虑到无法运行的简单 java 代码:

public class Bar extends AbstractBar{

    private final Foo foo = new Foo(bar);

    public Bar(){
        super(foo);
    }
}

我需要在

super()
调用之前创建一个对象,因为我需要将它推送到基类中。

我不想使用初始化块,我不想做类似的事情:

super(new Foo(bar))
在我的构造函数中..

如何在超级调用之前将数据发送到基类?

java superclass
3个回答
18
投票

如果

Foo
必须存储在一个字段中,你可以这样做:

public class Bar extends AbstractBar{    
    private final Foo foo;

    private Bar(Foo foo) {
        super(foo);
        this.foo = foo;
    }

    public Bar(){
        this(new Foo(bar));
    }
}

否则

super(new Foo(bar))
对我来说看起来很合法,如果你愿意,你可以将
new Foo(bar)
包装成
static
方法。

另请注意,字段初始化器(如您的示例中所示)和初始化器块也无济于事,因为它们在超类构造函数之后运行。如果字段被声明为

final
你的例子将不会编译,否则你会在超类构造函数中得到
null


1
投票

这在 Java 中是不可能的。唯一可能的解决方案是超级构造函数中的新调用。

如果 foo 对象可以在实例之间共享,您可以将其声明为静态

public class Bar extends AbstractBar{

    private static final Foo foo = new Foo(bar);

    public Bar(){
        super(foo);
    }
}

如果超类在你的控制之下,你可以重构它并使用模板方法模式将对象拉入构造函数而不是从子类中提取它。这适用于好莱坞原则:不要打电话给我们,我们会打电话给你;)

public abstract class AbstractBar{

    private Object thing;

    public AbstractBar(){
         this.thing = this.createThatThing();            
    }

    protected abstract Object createThatThing();
}

public class Bar extends AbstractBar {

     // no constructor needed

     protected Object createThatThing(){
          return new Thing();
     }
}

1
投票
class AbstractBar{
    public AbstractBar() {
    }
    public AbstractBar(Foo t) {
    }
}
class Bar extends AbstractBar{
    static Foo t=null;
    public Bar() {
        super(t=new Foo());
    }
}
class Foo{...}
© www.soinside.com 2019 - 2024. All rights reserved.