Java was never the quickest language in regards of new features compared to newer languages, but IMHO this is one of the reasons why most of the enterprise world still depends on it and will in the future.
It’s mostly compatible between versions, long-term-support is good, and there are many options to run it on. Even though some of this changed recently since Java 9 and the new release model…
We should always know the complete power of a language we’re using by knowing all the new features and might adapt our coding style. Some things are just syntactic sugar, but other features will help us to reduce and avoid bugs, or get rid of an external-dependency, or even increase performance with a simple code change.
Let’s check out the new features!
The try-with-resources statements
Dealing with I/O was quite cumbersome before Java 7. We have to make sure that resources will be closed eventually, even if an exception occurs, so we end up with a finally block:
This was a simplified example, maybe we should also check if the reader isn’t already closed?
With Java 7 and the new try-with-resources statement we can streamline this code and make it more readable!
The magic in the background is the new interface java.lang.AutoClosable which allows the automatic closing of resources at the end of the try-with-resources block.
Multiple resources are also supported, they are close in reversed order of declaration:
The try-with-resources statement is also a normal
try-block, so feel free to add
finally blocks, they are run after the resources are closed.
Only caveat is exception handling…
Of course, the closing of resources can throw exceptions.
But what happens if our code in the try block throws an exception AND the closing of the resource throws another one?
In this case, Java suppresses the closing exceptions, but they are reachable via
#getSurpressed() of the exception, courtesy of
switch with String literals
Starting with Java 7 the
switch statement is capable of handling
The comparison is case-sensitive .
switch statements generate more efficient bytecode compared to lots of chained
I don’t work much with binary in my code, but it’s still a nice addition: integral types (
long) are now as easily declarable as hex-number:
We can either use
0B as prefix and might left-pad the value with as many zeros as needed.
The advantage here is that you can better visualize and compare binary variables that might have a direct relationship to another, which wouldn’t be visible in another form of representation.
Improved numeric literals
Numeric literals (including the new binary literal) can now be written in a more comprehensible way, with underscores as separators:
Some restrictions occur on the placement of the underscore though:
- not at the beginning or end of a number
- not adjacent to the decimal point
- not adjacent to prefixes/suffixes (e.g.
Instead of multiple
catch-blocks we can now catch multiple exception types in a single block. It’s nice to have as many different catch blocks as we might need, but if handling them doesn’t differ we combine them with the pipe symbol
The generated bytecode won’t duplicate any code and will be smaller and more efficient compared to multiple identical catch blocks.
Improved generic type inference for creation
Generics are great except typing so many types:
With Java 7 we don’t need to specify the types on the creation part thanks to the diamond operator
Most likely your IDE is already removing redundant types, or at least you should configure it this way to remove some noise from your code.
Of course, there’s more to Java 7 than just these few new language features.
We should always thrive to embody changes to our toolchain if they provide us with simpler patterns, new features or better performance. Sometimes it might be even worth rewriting some code, but don’t force the new stuff on old code if not needed.