To investigate the underlying mechanisms of try-with-resources, we create below classes:
// exceptions/AutoCloseableDetails.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
class Reporter implements AutoCloseable {
String name = getClass().getSimpleName();
Reporter() {
System.out.println("Creating " + name);
}
public void close() {
System.out.println("Closing " + name);
}
}
class First extends Reporter {}
class Second extends Reporter {}
public class AutoCloseableDetails {
public static void main(String[] args) {
try (First f = new First(); // can have a semicolon
Second s = new Second()) {}
}
}
/* Output:
Creating First
Creating Second
Closing Second
Closing First
*/
when do not implement AutoCloseable(since 1.7) interface:
// exceptions/TryAnything.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// {WillNotCompile}
class Anything {}
public class TryAnything {
public static void main(String[] args) {
try (Anything a = new Anything()) {}
}
}
the compile error is:
FAILURE: Build failed with an exception.
* What went wrong:
Task 'TryAnything' not found in project ':exceptions'.
* Try:
Run gradlew tasks to get a list of available tasks. Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
What if one of the constructors throws an exception?
// exceptions/ConstructorException.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
class CE extends Exception {}
class SecondExcept extends Reporter {
SecondExcept() throws CE {
super();
throw new CE();
}
}
public class ConstructorException {
public static void main(String[] args) {
try (First f = new First();
SecondExcept s = new SecondExcept();
Second s2 = new Second()) {
System.out.println("In body");
} catch (CE e) {
System.out.println("Caught: " + e);
}
}
}
/* Output:
Creating First
Creating SecondExcept
Closing First
Caught: CE
*/
SecondExcept does not close.
When no constructors throw exception, but the body of the try throw exceptions:
// exceptions/BodyException.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
class Third extends Reporter {}
public class BodyException {
public static void main(String[] args) {
try (First f = new First();
Second s2 = new Second()) {
System.out.println("In body");
Third t = new Third();
new SecondExcept();
System.out.println("End of body");
} catch (CE e) {
System.out.println("Caught: " + e);
}
}
}
/* Output:
Creating First
Creating Second
In body
Creating Third
Creating SecondExcept
Closing Second
Closing First
Caught: CE
*/
Third does not close.
Finally, if at close() methods that throw exceptions:
// exceptions/CloseExceptions.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
class CloseException extends Exception {}
class Reporter2 implements AutoCloseable {
String name = getClass().getSimpleName();
Reporter2() {
System.out.println("Creating " + name);
}
public void close() throws CloseException {
System.out.println("Closing " + name);
}
}
class Closer extends Reporter2 {
@Override
public void close() throws CloseException {
super.close();
throw new CloseException();
}
}
public class CloseExceptions {
public static void main(String[] args) {
try (First f = new First();
Closer c = new Closer();
Second s = new Second()) {
System.out.println("In body");
} catch (CloseException e) {
System.out.println("Caught: " + e);
}
}
}
/* Output:
Creating First
Creating Closer
Creating Second
In body
Closing Second
Closing Closer
Closing First
Caught: CloseException
*/
references:
1. On Java 8 - Bruce Eckel
2. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/exceptions/AutoCloseableDetails.java
3. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/exceptions/TryAnything.java
4. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/exceptions/ConstructorException.java
5. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/exceptions/BodyException.java
6. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/exceptions/CloseExceptions.java