我有类Foo
有两种构造方式:
public Foo(Bar bar)
public Foo(Baz baz)
可以通过尝试使用资源习语从Bar
获得Baz
,例如
try (Baz baz = bar.expensiveFunction()){
// code here
}
我想做的是在Foo(Bar bar)
构造函数中,本质上是写
public Foo(Bar bar)
{
try (Baz baz = bar.expensiveFunction()){
this(baz);
}
}
但这是不允许的,因为this(b)
不在第一行。有谁知道我如何在 Java 中实现这一目标?当然,我可以使用initialise
函数,但我宁愿不这样做。
@Bathsheba的方法更好。 但我认为有一种方法可以只与构造函数一起使用......在某些情况下。
如果 Foo
类扩展Object
,则可以执行以下操作:
public Foo(Bar bar) {
this(bar.expensiveFunction(), true);
}
public Foo(Baz baz) {
this(baz, false);
}
private Foo(Baz baz, boolean close) {
super();
try {
// initialize
} finally {
if (close) {
baz.close();
}
}
}
如果new Foo(someBar)
在Foo
对象的初始分配中抛出 OOME,则该 OOME 将在调用 expensiveFunction()
发生之前发生,因此不会有要关闭Baz
。
但是,如果Foo
扩展了其他类,那么Foo(Baz, boolean)
中的super()
调用可能会引发异常......无法在Foo
中捕获. 如果您无法捕获异常,则无法关闭Baz
。
一种避免initialize
函数(例如,这意味着字段不能被final
(的另一种方法是将更"昂贵"的函数重构为static
:
public static Foo makeFoo(Bar bar){
try (Baz baz = bar.expensiveFunction()){
return new Foo(baz);
}
}
这应该在呼叫站点提供最小的污染。