Java started its life in the early 1990s as an attempt to develop an architecture-independent language that could be used in consumer electronics and other embedded contexts. It found itself in the right place at the right time when the web exploded in the mid-1990s and over the next 10 years became one of the mainstays of web development. Today, Java remains as popular as ever. It’s arguably the most popular programming language of our generation.
After all this time, it’s tempting to consider the language “finished” or at least think that the baggage of backward compatibility makes innovation difficult. But commercial owner Oracle continues to invest heavily in Java, and the now widely adopted Java 8 and upcoming Java 9 release includes significant new goodies for the Java developer.
Java 8 Lambda expressions allowed for a form of functional programming and in many cases radically simplify program structure. Lambda expressions allow functions to be passed as arguments to methods. Furthermore, they can represent anonymous functions that do not require explicit naming.
One of the advantages of functional programming is the ability to more easily implement parallelisable programs. Java 8 Streams builds on the Java 8 functional primitives to provide more elegant and parallelizable methods for processing Java collections (Java structures such as Lists and Maps).
Java 9 is still at least 6 months away but it has been feature complete for quite a while. One of the most noticeable new features is the JShell utility, which runs a simple Java shell. This shell can be used to execute arbitrary Java commands without having to create a whole runtime class. JShell can be used to test language structures, perform simple calculations or as a simple interpreter for automation tasks. The JShell is an example of a REPL (Read-Eval-Print-Loop) utility.
More fundamentally, Java 9 completely refactors Java’s modularity paradigm.
Anyone who’s programmed in Java will know that typically you import dozens of packages which contain library and other necessary classes. Each package is represented by a “JAR” file which contains package interface and implementation. Java searches for JAR files on a “classpath” analogous to the command line PATH used since time immemorial in DOS and UNIX.
Unfortunately, the JAR file/classpath mechanism allows for ambiguity when resolving dependencies, and creates security issues and performance problems. For instance, when one package needs an API the java runtime simply scans the classpath looking for that API. A hacker could arrange for malicious code to run by inserting a new package into the classpath. Furthermore, multiple versions of a JAR file might exist within the classpath – Java will simply load the one it encounters “first.”
Java 9 modules combine all the required packages into a single unit with explicit dependencies. Furthermore, the module explicitly defines which classes will be exposed to other modules. This further tightens encapsulation since a JAR file within a module might export an interface required by other JAR files within the module, but the module itself need not export all of those interfaces.
Oracle recently slipped the expected delivery date of Java 9 from March to September 2017 – and this has not been the first such delay. The modules implementation is so core to the Java framework and the Java framework has become so mammoth, that it’s becoming increasingly hard to implement major enhancements.
It’s often tempting to think of Java as a modern-day COBOL – dominant through sheer mass of existing implementations and trained programmers, but representing the past rather than the future. As we’ve seen, it’s getting harder for Java to maintain forward motion – the sheer mass of legacy creates an inertia that is hard to overcome. It’s also true that Java is not what the cool kids like to code in these days - more modern languages such as Go and Scala have that honour. Still, there’s life in the old girl yet….