Adrian D. Finlay
Sep 28, 2017 · 7 min read

Java 9 is here!


The Java Standard Edition (Java SE) JDK 9 was released on September 22, 2017. The release notes, describing the new changes, are available here.

The Java Enterprise Edition Specification (Java EE) SDK 8, although not the topic of this article, was released on September 22 as well. The release notes, describing the new changes, are available here.

This article will discuss the changes to the Java language introduced with Java SE Release 9. There are five of them. The Java Enhancement Proposal 213, known as JEP 213: Milling Project Coin was the community effort behind these changes[2]. I will be running the examples with the Oracle Official Java 9 JDK on my Linux Mint box.

Where to get Java 9?

Java SE Development Kit 9 — Downloads

Oracle Official Guide on Installing JDK 9

Notice that while you can download and manually install Java 9 with the tar balls available on Oracle’s web page, it’s less hassle (and recommended) to install Java 9 via your distribution’s package manager. For many distributions, the openJDK may be the only offering in the default package manager, although there are many repositories available across various distributions to install Oracle’s official JDK 9.

For those Running Fedora\SUSE Linux, see this article.
Normally, you should be able to double click the RPM and install or use rpm or zypper from the command line, but as of recent, that has been giving some problems.

OpenSUSE official installation guide.

For those Running Debian, Ubuntu, & Mint based systems: As of about 4 PM on Sept 25, the webupd8Team ppa has been updated in Apt to include the General Availability release of Java 9.

You can install Java 9 by doing the following:

1)Add the WebUpd8 PPA repository:
sudo add-apt-repository ppa:webupd8team/java

2)Update/Refresh the Package Repository:
sudo apt-get update

3)Install the Oracle Official Java 9 JDK
sudo apt-get install oracle-java9-installer

4) Set the Default Java Version (if needed)
sudo apt install oracle-java9-set-default

Understand that this will work if this is the only copy of the JRE/JDK on your system. If you are unsure run “whereis java” or “whereis javac” from the Terminal to figure it out. It is likely that you have at least one other copy of Java on your system as many other pieces of software rely on the JRE, such as LibreOffice, for example. The version of Java you will likely encounter will probably be the openJDK. You do not need to install it, both copies can coexist. If you have more than one copy of the JDK/JRE on your machine, you will want to specify one as the default. In this case, follow the instructions below.

What if I still need to use Java 8?

  1. Figure out which version of Java is the default
    sudo update-alternatives — config java
    sudo update-alternatives — config javac
    sudo update-alternatives — config ……

    Notice that Medium automatically formats “- -” as “ — “. We want two dashes, one after the other in the command. Understand also that these commands will update individual executables only.
  2. Set the Default
    You will be asked to specify by number corresponding to a directory which tool to use.

    Java 9 will be located in: /usr/lib/jvm/java-9-oracle/bin/….
    Enter the number corresponding with the location above.
  3. Test it
    java -version should return java version “9”
    javac -version should return javac 9

By running these commands you can effectively toggle between Java versions.

Without further adieu, let’s begin.

#1 Support for Private Interface Methods

It’s now legal to have code like this. This allows non-abstract interface methods (default, private, static methods) to share code.

Understand that it was illegal to have private methods in interfaces prior to JDK 9. Understand also that private methods can now have a body, unlike abstract methods. This is what would happen in Java 8.

#2 Elimination of Underscore by itself as a valid identifier

Farewell, _, we will not miss you.

Contrast that to the situation in Java 8.

#3 @SafeVarargs is now legal on private instance methods

In Java 9, we can now do this.

Prior to JDK 9, methods annotated with @SafeVarargs must be methods that cannot be overridden such as static methods & final instance methods.

#4 Effectively final variables are legal with try-with-resources statements

In Java 9, we can finally use existing resources (any object that implements java.lang.AutoCloseable can be used as a resource) that were declared as final outside of the try-with-resource statement as follows.

Prior to JDK 9, the resource used would have had to be declared and instantiated inside of try (…). What commonly ended up happening is that resources were declared outside of the try block and References were made to said resource within the try block.This led to some long, aesthetically unpleasant, & unnecessary code.

#5 The Diamond Operator is now legal with Anonymous Classes if the Argument Type of the Inferred Type is a Denotable Type

In Java, Denotable Types are types that you write in the Java programming language (byte, String, int, and so on.). Non-denotable types are types only known to the compiler. It is important to note that the denotable types in discussion will be Reference Types as you cannot, of course, use primitive types with Generic Type parameters. The object wrappers (Integer, Double, and so on.) can be used in the stead of primitives should you need such functionality.

Some Foreground: Java Standard Edition Release 7 brought Generic Type Inference. Generic Type Inference enabled the compiler, when executing the constructor to infer the type of the object based on the types declared in the reference to the object. This was mostly done to short what could be very verbose code. Take for example this bit of code:

Most of this code is unimportant to the point. The portion to focus on is the highlighted line ( line 5) and line 9. Notice that we make use of generic type inference in line 5 when we say “= new Tool<> ();” and omit the type parameter <String> within the diamond operator. Imagine if you had 5 type parameters and many constructor arguments? It’d be a long mess. The community decided that it was redundant to repeat the type parameters in the constructor call. Instead, the compiler can now infer the types, saving programmers some time. Type inference leads to less obfuscated code.

Now let’s examine the situation with anonymous classes. Here’s the subtlety. The inferred type of an anonymous class’s constructor may not be within the types supported by it’s signature [3]. This is a bit of Compiler magic. Remember that Anonymous Classes are created by the compiler. Consequently, an attempt of type inference may result in a non-denotable type.

Now the problem should be obvious. One way to remedy this would be to introduce language mechanisms to support compiler types (non-denotable types) in the class file signature. That would be a mess. Instead, provisions were made in Java SE 9 to allow the use of the diamond operator if the inferred type was denotable.

This was the situation in Java 8.

In Java 9, we can now do this:

Want the source? Grab it here.

Interested in Java? Join my Java group on Facebook:

Like my Content? Subscribe to my mailing list:

Don’t forget to give it a…. ;)

Works Cited

[1] —

[2] —

[3] — Java Community Process: JSR-034 Final Draft Specification

The Java Report

A curation of contemporary content on all things Java, JavaFX, JavaEE, and JVM technologies.

Adrian D. Finlay

Written by

@thewiprogrammer. Lover of learning, programming. Tech writer, Java aficionado. Proud mango, fishing, NBA addict! & more. Network w/ me @

The Java Report

A curation of contemporary content on all things Java, JavaFX, JavaEE, and JVM technologies.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade