Autocloseable
should always be used with try-with-resources
. At least Intellij inspection suggests it.
So, if I have a code that produces Foo
that implements Autocloseable
I should do:
try (final Foo foo = getFoo()) {
foo.doSomething();
}
But what if I have function that returns Foo[]
? Or function that accepts Foo[]
(or Collection<Foo>
) as its argument?
How can I use it with try-with-resources
?
Looks at the following functions:
Foo[] getFoos();
doAll(Foo... foo);
I want to do something line doAll(getFoos())
How can I do that?
Try-with-resources statement can only close those resources, that were declared and assigned within its header. So the only way is to make the Collection you are getting implement AutoCloseable or wrap it into your AutoCloseable extension, so its close() method will be called by T-W-R. Like:
try (SomeAutoCloseableCollction col = getAutoCloseables()) {
System.out.println("work");
} //col.close() gets called
For an array, I'm afraid there is no way, since you can't extend it and make it implement some interface.
If you were to close collection by yourself, may be look at Apache Drill project and class org.apache.drill.common.AutoCloseables
- it does exactly that, closing lots of AutoCloseables by itself.
You can create methods for combining AutoCloseable
s to a single one which will safely close all of them:
public static AutoCloseable closeBoth(AutoCloseable a, AutoCloseable b) {
if(a==null) return b;
if(b==null) return a;
return () -> { try(AutoCloseable first=a) { b.close(); } };
}
public static AutoCloseable closeAll(AutoCloseable... c) {
return Arrays.stream(c).reduce(null, MyClass::closeBoth);
}
They allow to use the array returning method like
Foo[] foo;
try(AutoCloseable closeAll = MyClass.closeAll(foo=getFoos())) {
/*
use foo
*/
}
As the other answer states this isn't really possible. However you should ask yourself why you would need to put the whole collection in an AutoCloseable. If you want to make sure each element is closed after processing, you can do something like:
Foo[] foos = getFoos();
for (int i = 0; i < foos.length; i++) {
try (Foo foo = foos[i]) {
// Your code here
}
}
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