A helper for closing multiple resources and re-throwing only one exception,
Throwable#addSuppressed(Throwable) the others as necessary.
This class is not thread safe.
This helper is mainly useful when implementing
AutoCloseable#close()or a similar closing method in your own class, to make sure that all resources are
at least given the chance to close, even if closing one of them fails.
When creating then closing resources in the scope of a single method call,
try-with-resource blocks should be favored.
See the
AbstractCloser superclass for a list of methods
allowing to close objects while catching exceptions.
Warning: In order not to ignore exceptions,
you should always call
Closer#close()once you closed all of your resources. The most straightforward way
to do this is to use a try-with-resource block:
public void myCloseFunction() throws MyException {
try ( Closer<MyException> closer = new Closer<>() ) {
closer.push( this.myCloseable::close );
closer.pushAll( this.myListOfCloseables, MyCloseableType::close );
}
}
Exception type
Note that the closer has a generic type parameter, allowing it to
re-throw a given checked exception.
If you don't want to use this feature, you can simply use a
Closer.
If you need to close multiple resources throwing different checked
exceptions, and those exceptions don't have a practical common superclass,
you can "split" the closer:
public void myCloseFunction() throws IOException, MyException, MyOtherException {
try ( Closer<MyException> closer1 = new Closer<>();
Closer<IOException> closer2 = closer1.split();
Closer<MyOtherException> closer3 = closer1.split() ) {
closer2.push( this.someJavaIOCloseable::close );
closer1.pushAll( this.myListOfCloseables1, MyCloseableTypeThrowingMyException::close );
closer3.pushAll( this.myListOfCloseables2, MyCloseableTypeThrowingMyOtherException::close );
}
}
The multiple closers will share the same state, which means the first
exception to be caught by any of the closers will be the one to be re-thrown,
and all subsequent exceptions caught by any closer will be added as suppressed
to this first exception.
Be careful though, you will have to close every single closer.
Closing just the original one will not be enough.