Java 7: The Top 8 Features
t’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.
Java Releases
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
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.