What Java 9 Brought
Want to learn more about the features in Java 9? Check out this post to learn more about Java 9, including private interface methods, valid identifiers, and more!
Join the DZone community and get the full member experience.Join For Free
The Java Standard Edition (Java SE) JDK 9 was released on September 22, 2017. The release notes, describing the changes, are available here.
This article will discuss the changes to Java that were introduced with the 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 . I will be running the examples with the Oracle Official Java 9 JDK on my Linux Mint box.
Where to get Java 9?
Notice that, while you can download and manually install Java 9 with the tarballs available on Oracle's web page, it's less of a 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, check out 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 us some problems.
The OpenSUSE official installation guide is available here. For those running Debian, Ubuntu, and 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 performing the following tasks:
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 as long as 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, like 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?
- Figure out which version of Java is the default
sudo update-alternatives — config java
sudo update-alternatives — config javac
sudo update-alternatives — config.
We want two dashes — one after the other in the command. Understand that these commands will update individual executables only.
- Set the Default — You will be asked to specify by the number corresponding to a directory on 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.
- 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!
Java 9 Language Features
Support for Private Interface Methods
It's now legal to have code like this. This allows non-abstract interface methods ( default, private, and static methods) to share code.
Understand that it was illegal to have private methods in interfaces prior to JDK 9. Understand that private methods can now have a body, unlike abstract methods. This is what would happen in Java 8.
Elimination of Underscore as a Valid Identifier
Farewell, _, we will not miss you.
Contrast that to the situation in Java 8:
@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 and final instance methods.
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-resources statement shown below:
Prior to JDK 9, the resource used would have been 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 call a resource within the try block. This led to some long, aesthetically unpleasant and unnecessary code.
The Diamond Operator Is now Legal With Anonymous Classes
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 (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 this discussion will be reference types. This is because 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: The Java Standard Edition Release 7 brought us the generic type inference. The generic type inference enabled the compiler when executing the constructor to infer the type of object based on the types declared in the reference to the object. This was mostly done to create efficient, concise code that, otherwise, could become very verbose. Take for example this bit of code:
Most of this code is unimportant. 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 five 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 its signature . 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.
Published at DZone with permission of Adrian D. Finlay, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.