Java 7 - Spare Some Change?
That Was Some Catch!
When you make proper use of Java exceptions, it should lead to less code overall. For example, without exception handling, you need to write guarded code, checking every return value and all preconditions to avoid fatal errors. With exceptions, you can eliminate all of that code, and just assume the go-right path all the time, knowing your exception block will get executed if something goes wrong. However, this can get verbose when using API calls that throw different types of exceptions. For example:
try {
//...
} catch ( IOException x ) {
logger.log( ... );
throw x;
} catch ( SQLException s ) {
logger.log( ... );
throw s;
} catch ( Exception e ) {
// handle differently
}
Since there are multiple exceptions that are handled the same way, the result is duplicated code. With Java 7's new multi-catch syntax, this can be replaced with the following:
try {
//...
} catch ( IOException | SQLException x ) {
logger.log( ... );
throw x;
} catch ( Exception e ) {
// handle differently
}
Continuing with the enhancements to exception handling, Java 7 introduces the new try-with-resources syntax to help avoid the verbose, error-prone exception handling code that's often associated with IO. For example, examine this file IO code:
static void copy(Path src, Path dest) throws IOException {
InputStream is = Files.newInputStream(src);
OutputStream is = Files.newOutputStream(dest);
try {
byte[] b = new byte[SIZE];
int n;
while ((n = in.read(buf)) >= 0 )
out.write(buf, 0, n);
}
finally {
in.close();
out.close();
}
}
Many Java programmers errantly place the calls to close() within the finally block, but this isn't perfect. Yes, this block of code will be executed after all the other code has completed, which is good, but what happens if either close results in an exception? The result could be a resource/memory leak. You could wrap each call within the finally block within its own try-catch block, but that quickly gets out of hand. Java 7's try-with-resources uses the JVM to handle all of the clean up for you, without the need for all of the old try-catch-finally code:
static void copy(Path src, Path dest)
throws IOException {
try (InputStream is = Files.newInputStream(src);
OutputStream is = Files.newOutputStream(dest) )
{
byte[] b = new byte[SIZE];
int n;
while ((n = in.read(buf)) >= 0 )
out.write(buf, 0, n);
}
}
Here, the resources that need to be closed, which could also result in an exception when used, are wrapped within the try clause at the beginning of the scope. The JVM will ensure these resources are closed/cleaned up after the code has completed, and regardless of errors that occur. To make this work, Java 7 has introduced the concept and interface called AutoCloseable:
public interface AutoCloseable {
public void close() throws IOException;
}
All resource objects that are to take advantage of try-with-resources must implement this new interface. For the JDK, this has been done for all streams, readers, writers, channels, JDBC APIs, and file-lock APIs. It can even be made to work with your own APIs.
Conclusion
These are some examples of the updates and improvements Project Coin has brought to the Java language. Other smaller examples you can research on your own include improvements to how caught exceptions are rethrown, literals that can new contain underscores for improved readability, and safe variable argument processing for methods. On top of it all, Java 7 and Project Coin's syntax improvements are supported by the Eclipse, NetBeans, and IntelliJ IDEs.
Happy Coding!
-EJB

