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

Posted

技术标签:

【中文标题】在java中的super调用之前创建一个对象【英文标题】:create an object before the super call in java 【发布时间】:2012-06-19 15:30:05 【问题描述】:

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

public class Bar extends AbstractBar

    private final Foo foo = new Foo(bar);

    public Bar()
        super(foo);
    

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

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

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

如何在超级调用之前向母类发送数据?

【问题讨论】:

你想做什么?更大的问题是什么? 为什么不希望 super(new Foo(bar)) 在构造函数中? Foo 构造函数中的 bar 是什么? 我不想那样做,因为我有很多字段要传入构造函数.. 【参考方案1】:

如果必须将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

【讨论】:

【参考方案2】:

这在 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();
     

【讨论】:

【参考方案3】:
class AbstractBar
    public AbstractBar() 
    
    public AbstractBar(Foo t) 
    

class Bar extends AbstractBar
    static Foo t=null;
    public Bar() 
        super(t=new Foo());
    

class Foo...

【讨论】:

以上是关于在java中的super调用之前创建一个对象的主要内容,如果未能解决你的问题,请参考以下文章

java中的super()是啥

java中的super

如何在java中子类中父类的对象如何调用父类的方法?

super关键字

随笔14 java中的关键字

java中this和super的用法怎么用?