It’s been a while since the last major Java release and expectations were naturally high for the upcoming release. The Java 7 release initially included many JSRs with exciting features, like support for closures, which were later deferred to Java 8 in order to release JSRs that are already done. This effectively diluted what is now offered in Java 7 and has left some disappointed.
The Java language has undergone major changes since I started using it in 1998. Most of the changes were driven by the Java Community Process (JCP) which was established in 1998 as a formal and transparent process to let interested individuals and entities participate and influence how the language should evolve. This is done through the submission of a change request, known as Java Specification Request (JSR), followed by a review and a voting process. Changes or enhancements made to the language can be usually tracked back to a JSR where they were originally put forward for review. For example, the addition of Generics in Java 5 was done via JSR 14.
Here’s a quick snapshot of the past Java release dates (table 1). There are several small new features and enhancements in Java 7. Out of the 28 features that I looked at, here are the ones that I found useful.
New features and enhancements
#1 Strings in switch
In programming, we often encounter situations where we need to do different things based on different values of a variable. For Boolean variables, an if-then-else statement is the perfect way of branching code. For primitive variable types we use the switch statement. However, for String variables, we tend to resort to using multiple if-then-else branches as follows.
Java 6 and Before
One workaround for this is to convert the String into an enum and then switch on the enum.
Java 7, however, has added a language level support for String in switch. Now you can rewrite the same code more elegantly:
Not only does this help us write more readable code, but it also helps the compiler generate more efficient byte code as compared to the if-then-else by actually switching on the hashcode() and then doing an equals() comparison. Please note that you will get a NullPointerException if the variable language in the above example resolves to null. I like this feature, but unlike some of the other enhancements in the past (like Generic in Java 5), I don’t anticipate using this feature a lot. Practically, I find myself using if-then-else for one or two values and resort to an Enum when the number of values are higher.
#2 try-with-resources statement
One of the most useful additions in Java 7 is the auto closing of resources like InputStream which helps us reduce boiler plate code from our programs. Suppose we were writing a program which reads a file and closes the FileInputStream when it’s done, here is how you would write the program:
With Java 6 and Before
I want to point out a couple of things in this code. Firstly, notice that we declare the FileInputStream outside the try block just so that it can be accessed in the finally block. The second observation is that we need to initialize the InputStream to null, so that it is guaranteed to be initialized when we access it in the finally block. Last but not the least, the is.close() in the finally block may throw an Exception as well, thereby hiding the original Exception thrown in the try block Exception from the caller. What we probably want is to handle the Exception thrown from is.close() and throw the original IOException.
The above code still has a shortcoming that the Exception thrown from finally is supressed and not accessible to the calling code. I’m not sure how often we want to get both the original Exception and also the Exception thrown from the finally block, but if we did want it, we could do always do something like this:
SuppressedException above is a user written Java bean with a field named suppressed of type Exception. The calling code can then call SupressedException.getThreadLocal().getException() to get the Exception that was supressed in the finally clause. Great, we solved all the problems associated with the try-catch-finally! Now we must remember to repeat this exact sequence with each use of try-catch-finally when handling files or other resources which need to be closed. Enter Java 7, and we can do the above without the boiler plate code.
With Java 7
try can now have multiple statements in the parenthesis and each statement should create an object which implements the new java.lang.AutoClosable interface. The AutoClosable interface consists of just one method.
Each AutoClosable resource created in the try statement will be automatically closed! If an exception is thrown in the try block and another Exception is thrown while closing the resource, the first Exception is the one eventually thrown to the caller. The second Exception is available to the caller via the ex.getSupressed() method. Throwable.getSupressed() is a new method added on Throwable in Java 7 just for this purpose.