One of the many things I like about Java, the language, is that Sun revved it regularly. Not too often and not too much. I’ve previously written about this generally prudent schedule of releases and strongly encouraged stragglers to get to Java 5, which was a truly watershed release. Java 6 was less important and could easily be skipped over in favor of migration to Java 7, which is due out in late Q3.
Java 7 looks like a major release. The language has been made easier to program with, the JVM now supports dynamic languages well, and the libraries have been expanded and improved.
Let me start with the language, where syntactical sugar—surely inspired by various other JVM languages—has been added. The redundant boilerplate for defining generics has been eliminated. Generics add important safety features to the language, but they have two drawbacks: They can become exceedingly complex and they’re verbose. Complexity seems inevitable, but the verbosity has been reduced by changes in Java 7.
In addition, strings can now be used as case statements in a switch (technically, this too is syntactical sugar). Also added was an update to the varargs (variable number of arguments passed to a method) capability. It can better handle generics in the method call.
An important feature for resource de-allocation has also been added: Resources opened within a try block are automatically closed at block exit. This prevents resource leaks and makes some exception handling easier. Of these language changes, the strings in a switch statement will likely see fast adoption.
The loudest lament in the Java community is that Sun/Oracle did not tackle the problem of multiple exceptions. Right now, as all Java developers know, lots of Java must be banged out to handle code blocks that can throw multiple exceptions. Frequently, the exception handlers all do the same thing (print a stack trace or an error message, etc.), but the commands have to be repeated for every possible thrown exception. A widely supported simplification would allow all the exceptions that trigger the same operation to be declared in a single catch block. That change, long under consideration but finally turned down, would have been a very useful feature.
The JVM in Java 7 provides distinctly better support for dynamic languages by adding the invokedynamic bytecode. This addition solves a curious problem. As readers know, Java is a statically typed language, whereas dynamic languages tend not to be. Interestingly, the compiled Java bytecodes drop much of the type information because the JVM does not use it. (This language-level-only enforcement of a feature occurs in other parts of Java, such as generics.)
However, method invocation in the JVM does require type info and strict type matching. So, generating method calls where the type information is not known until runtime (as needed for dynamic languages) relied on a Rube Goldberg scheme involving the convoluted use of reflection. Invokedynamic, or its larger ecosystem, JSR 292, addresses this issue, and now dynamic languages on the JVM will run much faster. In my opinion, this change is the one that will most likely drive early adoption of the new release.
The JVM also improves performance of Java code with faster garbage collection. The new G1 garbage collector runs faster, performs better on parallel code, and, crucially, does heap defragmentation.
As to the libraries, there are many additions, especially in socket management. Also, direct support for elliptical curve cryptography is now provided.
Most useful to everyday development will be NIO.2, which is a group of advances in coding file I/O. It adds better path management, easier recursive functions on directories, with special handling for large directories, and (finally!) access to file attributes.
Finally, developers doing parallel programming will enjoy working with Parallel Arrays and the Fork/Join framework added through adoption of JSR-166y (JSR 166 was the initial concurrency JSR, x was a previous extension, y is the extension for this release). This framework enables developers to define predicates (actions) and mapping operations, chain them together, and point them at a collection. Java will execute them in parallel, correctly and safely. In many ways, this approach is similar to dataflow programming and enables large-scale data management to be done with comparatively little code.
As with previous Java releases, Java 7 sprinkles fairy dust in a lot of different areas. The urge to update frequently is lit by the allure of one attractive bauble, but consummated when the realization comes that you’re solving a problem already addressed in the new release. In Java 7, I see a lot of baubles.
Andrew Binstock is the principal analyst at Pacific Data Works. Read his blog at binstock.blogspot.com.