Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a delegated constructor with try-with-resources idiom within another constructor

Tags:

java

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.

like image 377
Dom Alvarez Avatar asked Nov 21 '25 04:11

Dom Alvarez


2 Answers

@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.

like image 138
Stephen C Avatar answered Nov 22 '25 18:11

Stephen C


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.

like image 40
Bathsheba Avatar answered Nov 22 '25 17:11

Bathsheba



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!