Below, I have provided some of the most important core language enhancements for JDK 9.0.The objective of this article is to introduce you to the new features of Java SE 9. This includes mostly conceptual introduction of the features. These are the almost finalized features, that have been accepted and officially announced by Oracle. Java 9 is scheduled for release by about the end of July 2017.

List of Changes in JDK 9

As a developer, the ones that impact our day-to-day lives mostly fall in the areas of:

Java language in JDK 9

Core libraries in JDK 9

Official Oracle Release: July 2017

Even though others are also very important, they can be studied, researched, and mastered if and when the need arises. Before we get into the Java 9 changes, let us touch on one aspect of Java 8 that we need to know more about.

Default Interface Methods

Whenever there is existing or legacy code that has Interfaces that require the addition of new methods, it causes breakage of existing classes that inherit/implement from this Interface, unless the implementation for each of these added methods is provided in the classes. This does not make for very maintainable code. Even though a good practice, as per SOLID and other OO paradigms, is to provide an interface without any implementation, we need to handle and solve the problem as mentioned above. This is where Default Interface Methods come in.

From the example above, the LegacyPublicInterface in an existing application is already extended by multiple invoice types (for example, in an inventory system). But as per changing business requirements, re-engineering effort requires that each of the invoices have a method to invalidate or remove an item marked with "OOS". Given such a problem, prior to Java 8, we would have had to introduce a new method declaration in the interface and then require that each of the implementing classes implement their own logic for handling this.

With Default Interfaces, the task becomes very simple (the code is now more maintainable and extensible and requires much less effort to change). With the introduction of this feature of Default Methods, the following are the possibilities:

Use the default method(s) without breaking existing functionality (best use).

The implementing class can choose to override these default methods.

Abstract classes can be provided over the Interfaces to override implementation.

So, let's get further into each of these changes in Java 9, one-by-one.

Java Language in JDK 9

JEP 213: Milling Project Coin

@SafeVarargs Allowed on Private Instance Methods

Using non-reifiable variable argument parameters in a method can cause multiple warnings when trying to compile code, such as:

Hence, @SafeVarargs were introduced to suppress such warnings on unchecked or unsafe operations. By using this, developers are signaling to the compiler that they have made sure that there will be no Heap Pollution (such as unsafe forEach operations) caused.

Prior to Java 9, @SafeVarargs were allowed on non-overridable methods such as in static methods, final instance methods, and constructors. Note that the annotation will throw an error if it is used in fixed arity methods.

In Java 9, @SafeVarargs can be used on private instance methods.

Underscore as a Variable Name Is not Legal Anymore

Using only the _ (underscore character) as a variable name is not legal anymore.This is because it is marked as a reserved keyword from Java 1.8 (But causing compilation failure only in Java 1.9).

This may cause some issues when compiling legacy source code, especially that which had a necessity to denote some specific resource or entity using the _ (underscore). It may have to be rewritten and may have many related ramifications.

Private Interface Methods Have Been Introduced

Interfaces in Java 9 are allowed to have Private Methods. This was done to allow code sharing between non-abstract methods in the Interface. All rules related to ordinary Private modifier apply to these methods. The point to note is that a method cannot be both private and abstract. It definitely needs to have a method body.

Allow Effectively final variables to be used as Resources in Try-With-Resources

Up to Java 8, every variable that had to be used within Try-with-Resources statements needs to be declared within the try statement. Only then can it be used within the try block. This is a limitation for the developer. Hence, in Java 9, this restriction has been removed and any final variable or effectively final (local) variable can be used inside the try block. All other rules as applicable to Try-with-Resources continue. Effectively Final means the variable that is not changed once after it has been initialized.

Allow Diamond with Anonymous Classes If the Inferred Type's Argument Type is Denotable

Up to Java 8, using Generics and Diamond Operators with Anonymous Classes. It was mainly because the compiler could not infer whether it can represent the type in the Argument passed to the Diamond Operator. JSR 334 has the following to say about using diamond with anonymous classes:

"Using diamond with anonymous inner classes is not supported since doing so in general would require extensions to the class file signature attribute to represent non-denotable types, a de facto
JVM Change."

"Internally, a Java compiler operates over a richer set of types than those that can be written down explicitly in a Java program. The compiler-internal types which cannot be written in a Java program are called
non-denotable types. Non-denotable types can occur as the result of the inference used by diamond. Therefore, using diamond with anonymous inner classes is not supported since doing so in general would require extensions to the class file signature attribute to represent non-denotable types, a de facto JVM change. It is feasible that future platform versions could allow use of diamond when creating an anonymous inner class as long as the inferred type was denotable."

With Java 9, the Java compiler has changed its inference algorithm in a way that Diamond Operator (Generics) can now work simultaneously with Anonymous Classes, as long as the Argument type of the Inferred type is Denotable. The important point to note is that things that fall under Denotable are Primitive types, Raw types, and non-Generic types. Non-Denotable means ones that cannot be written in a Java Program, like usage of Extends and Super along with Wildcard types in Generics. These are usually inferred by the compiler. So, as long as the compiler identifies that the Argument type of Inferred type is Denotable — you can use the Diamond Operator in conjunction with Anonymous Inner Classes.

Core Libraries in JDK 9

JEP 102: Process API Updates

With Java 9, one can retrieve the PID of the process through a native call. This is achievable through the ProcessHandle. Also, we can retrieve information about the currently running Java process (JVM) and Info (inner class of ProcessHandle) Class/Object that contains details on the process. We can also enlist or return a snapshot of all currently running processes in the system.

JEP 193: Variable Handles

Java's Concurrent Package (java.util.concurrent.atomic) provide all atomic types for performing atomic operations. Apart from this, Unsafe Operations (sun.misc.unsafe), such as creating objects without calling the constructor used in Java low-level programming need to be hidden from the outside world as per JEP 260: Encapsulate Most Internal APIs. This has led to the creation of a new abstract class type named VarHandle. This will allow a developer to assign different types to the same reference (dynamically typed references). It can also take care of performing atomic operations on the held variable, including compare and swap (set or exchange) operations. It also provides memory fencing operations, to order the in-memory representation of the object, by providing finer grain control.

JEP 254: Compact Strings

Although this has no external ramification to a developer in terms of syntax or semantics change, it may impact the way we design for memory and performance. The current UTF-16 representation uses 2 Bytes for Storage. Most of the string contain characters that are only Latin-1 in nature. The Latin-1 characters require only 1 Byte for Storage. With Java 9, String storage has been modified to start with an Additional Encoding Flag. This flag indicates whether it contains ISO-8859-1/Latin-1 characters or the UTF-16 characters. As per the official word, it has led to an improved usage of memory and efficient GC, but with some loss in performance at peak loads.

JEP 264: Platform Logging API and Service

This defines a minimal logging API for the platform and also provides a Service Interface for the consumers of these messages. The implementation for this interface can be provided by logging libraries or application itself to route the messagesappropriately to the application specific logging framework or implementation being used such as [Log4J or SLF4J]. Whenever an implementation is not available, the run-time switches to Default Java Logging Package. (java.logging). This also allows us to detect Bootstrap issues.

JEP 266: More Concurrency Updates

There is a continually evolving thought process on concurrency. With Java 9, An interoperable Publish-Subscribe framework has been provided. Also, enhancements to the CompletableFuture object has been provided, along with numerous implementation improvements over JDK 8, including Javadoc rewording. An interoperable Publish-Subscribe framework, also known as Reactive Streams,allow two-way communication based on the traffic or volume at each end of the stream, Publisher and Subscriber. The enhancements to the CompletableFuture API include methods that allow a Future to complete with a value or with an exception, after a Timeout period. Also, a Delayed Executor has been provided to allow a task to execute after some delay.

JEP 268: XML Catalogs

An XML catalog is made up of entries from one or more Catalog entry files. A Catalog entry file is an XML file whose document element is Catalog and whose content follows the XML Catalog DTD defined by OASIS. With Java 9, there is a public API for XML Catalog management. The external references in the catalog needed to be resolved repetitively. But with this new API, an API containing CatalogManager, Catalog, and CatalogResolver can be used to reduce or eliminate these external invocations, when the catalog resource already exists locally. It creates a Local Catalog and will allow JAXP-based processors to resolve to this local catalog.

JEP 269: Convenience Factory Methods for Collections

This addition makes it convenient for developers to create Immutable Collections out of existing collections, be it Set, Map, or List. A static factory method of() added to each of the interfaces — Set, Map and List. It is important you understand the following (even though consistent with previous versions of Java):

They are Structurally Immutable.

They Disallow Null elements or null keys.

They are Serializable if all elements are serializable.

They Reject Duplicate Elements/Keys at creation time.

The Iteration Order of set elements is Unspecified and is Subject to Change.

They are Value-Based. Factories are free to create new instances or reuse existing ones. Therefore, Identity-Sensitive Operations on these instances (Reference Equality (==), Identity Hash Code, and Synchronization) are Unreliable and should be Avoided.They are serialized as specified on the Serialized Form page.

JEP 274: Enhanced Method Handles

A method handle is a typed, directly executable reference to an underlying method, constructor, field, or similar low-level operation, with optional transformations of arguments or return values. These transformations are quite general and include such patterns as conversion, insertion, deletion, and substitution.

JEP 277: Enhanced Deprecation

With an eye on maintainable and more informative code, developer-defined deprecation now allows us to mark deprecation with additional elements of information like forRemoval and since. The forRemoval allows us to mark that this item may be removed in future versions of Java, and since provides information about when it was first introduced.

JEP 285: Spin-Wait Hints

For multi-threading applications, this brings in some performance improvements under Busy-Waiting or Spin-Waiting conditions. Usually, Busy-Waiting is done for synchronization of some state of the object between two or more invokers - Waiting for a condition to occur before processing starts or continues. Thread.onSpinWait() has been introduced as a static method in the Thread class and can be optionally called in Busy-Waiting loops.

This will allow the JVM to issue processor instructions on some system architectures to improve reaction time in such Spin-Wait loops and also reduce the power consumed by the core thread or hardware thread. This benefits the overall power consumption of a program and possibly allows other cores or hardware threads to execute at faster Speeds within the same power consumption envelope.

JEP 290: Filter Incoming Serialization Data

This feature is related to the addition of filters at the serialization incoming streams to improve security and robustness. The core mechanism is a filter interface implemented by serialization clients and set on an ObjectInputStream. The filter interface methods are called during the deserialization process to validate the classes being deserialized, the sizes of arrays being created, and metrics describing stream length, stream depth, and number of references as the stream is being decoded. The filter returns a status to accept, reject, or leave the status undecided.

JEP 259: Stack-Walking API

Prior to Java 9, the way to access Stack Trace was very limited and provided the entire dump or stack information at once. This was inefficient and did not allow any direct way of filtering data. With Java 9, a Lazy StackWalker API has been introduced. This will allow us to fetch data based on filtering conditions and is more efficient.

Full Speed Ahead, with Java 9!

Ready Reference on DZone

You may have noticed, that unlike my other articles, I have not provided code samples against each of the new features. The articles that I refer to here include my series of articles on the history of Java SE releases, right from Java SE 5. I will extend this current article that you are reading with detailed code samples (as these are new features) some time later. I will publish the same under 'SKP Java/Java EE Gotchas' series of articles. Until then, I request you to read the above article again and let all the concepts settle in.