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.