I have class Foo that has two ways of being constructed:
public Foo(Bar bar)
public Foo(Baz baz)
It's possible to get a Baz from a Bar with a try with resources idiom like
try (Baz baz = bar.expensiveFunction()){
// code here
}
What I want to do is in the Foo(Bar bar) constructor, essentially write
public Foo(Bar bar)
{
try (Baz baz = bar.expensiveFunction()){
this(baz);
}
}
but this is not allowed as this(b) is not on the first line. Does anyone know how I can achieve this in Java? Of course, I could use an initialise function, but I'd rather not do that.
@Bathsheba's approach is better. But I think there is a way that works with just constructors ... in some circumstances.
If the Foo class extends Object, you can do this:
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();
}
}
}
If new Foo(someBar) throws an OOME in the initial allocation of the Foo object, that will occur before the call to expensiveFunction() occurs, so there will be no Baz to be closed.
But if Foo extends some other class, then the super() call in Foo(Baz, boolean) could throw an exception ... which cannot be captured in Foo. And if you can't capture the exception, then you can't close the Baz.
One alternative, which avoids an initialize function (which would mean, for example, that fields couldn't be final), is to refactor the more "expensive" function into a static:
public static Foo makeFoo(Bar bar){
try (Baz baz = bar.expensiveFunction()){
return new Foo(baz);
}
}
which ought to afford minimal pollution at calling sites.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With