ARM:
One of the useful features in Java7 is the Automatic resource management via the try-with-resources statement.
In the olden days thou would (or atleast were supposed to) code like:
void doSomething() throws IOException {
OutputStream out = null;
try {
out = new FileOutputStream("");
out.write(data);
} finally {
if (out != null) {
out.close();
}
}
}
Which is error prone if you do forget to close the resources.
The new way is:
void doSomethingNew() throws IOException {
try (OutputStream out = new FileOutputStream("")) {
out.write(data);
}
}
This is syntactically much more pleasing and does the right thing internally.
Going deep:
The try-with syntax works with any
AutoCloseable implementation and you can have multiple resources as well.
The compiler will transform the above code into something like:
void doSomethingNew() throws IOException {
OutputStream out = null;
Throwable localThrowable1 = null;
try {
out = new FileOutputStream("");
out.write(blah);
} catch (Throwable localThrowable2) {
// We keep a reference to which can add a suppressed exception
localThrowable1 = localThrowable2;
throw localThrowable2;
} finally {
if (out != null) {
if (localThrowable1 != null) {
// Already have an exception thrown
try {
out.close();
} catch (Throwable localThrowable3) {
// Add the suppressed exception during close
localThrowable1.addSuppressed(localThrowable3);
}
} else {
// Potentially throw an IOException due to failure when close'ing
out.close();
}
}
}
}
The pattern is:
- If there are no exception - close() in the finally block OR
- If there are no exception during operation but there is an exception during close() then throw it OR
- If there is an exception thrown then throw it after closing the resource OR
- If there is an exception1 thrown then throw it .. and if there is an exception2 closing the resource.. then exception1.addSuppressed(exception2). This is new in theThrowable class
Sidenote:
There was a huge effort to get closures into Java7 but none of the solutions was light on syntax/complexity. After the backlash over Generics a smaller but better step has been taken.
Sidenote++:
For scala see
using. You do not need to wait for language changes to make syntactically pleasing APIs because of curry-ing and other fancy stuff.
More References:
ARM spec
Article on ARM