2010-10-07 86 views
5

这就是我想要做的(在Java中1.6):如何在Java中实现构造函数包装?

public class Foo { 
    public Foo() { 
    Bar b = new Bar(); 
    b.setSomeData(); 
    b.doSomethingElse(); 
    this(b); 
    } 
    public Foo(Bar b) { 
    // ... 
    } 
} 

编译器说:

call to this must be first statement in constructor 

有什么解决方法吗?

回答

17

你需要实现这样的:

public class Foo { 
    public Foo() { 
    this(makeBar()); 
    } 
    public Foo(Bar b) { 
    // ... 
    } 
    private static Bar makeBar() { 
    Bar b = new Bar(); 
    b.setSomeData(); 
    b.doSomethingElse(); 
    return b; 
    } 
} 

makeBar方法应该是静态的,因为对应于this的对象不是可在您所呼叫的方法点。

顺便说一句,这种方法的优点是它不会一个完全初始化Bar对象传递给Foo(Bar)。 (@RonU指出,他的做法没有。当然,这意味着他的Foo(Bar)构造不能想当然地认为其Foo说法是最终状态,这可能是有问题。)

最后,我同意,一个静态工厂方法这是一种很好的替代方法。

+0

这是否真的回答第二个构造函数上的邮件? – RonU 2010-10-07 12:47:47

+3

*回复邮件* ??? – 2010-10-07 12:51:59

+0

@RonU - 国际海事组织,我的回答直接解决了OP的问题。如果您不同意,请解释原因。 – 2010-10-07 13:18:11

5

可以实施“默认构造函数”作为一个静态工厂方法:

public class Foo { 
    public static Foo createFooWithDefaultBar() { 
    Bar b = new Bar(); 
    b.setSomeData(); 
    b.doSomethingElse(); 
    return new Foo(b); 
    } 
    public Foo(Bar b) { 
    // ... 
    } 
} 
-1

像它说,这个()的调用必须在构造函数来发生的第一件事情。这有什么理由不起作用吗?

public class Foo { 
    public Foo() { 
    this(new Bar()); 
    Bar b = getBar(); 
    b.setSomeData(); 
    b.doSomethingElse(); 
    } 
    public Foo(Bar b) { 
    // ... 
    } 
} 
+0

它可能会工作,但它是屁股 - 丑陋的:-) – 2010-10-07 12:51:24

+0

没有关于这个的争论。对我而言,这些情况往往会变成我所要求的那样 - 我真的想要那个构造函数,通常答案是否定的,因为我认为这是错误的。我宁愿让实例化器传递一个完全配置的Bar(第二个构造函数),然后继续。 – RonU 2010-10-07 13:05:47

+2

这是行不通的,因为'Foo(Bar b)'可能对'b'做一些操作,这必须在'b'初始化后发生。 – yegor256 2010-10-08 09:48:59