Since the release of Java SE 8, all the developers were under the charm of the Lambdas, Streams and even there those who fell in love with Nashorn for years (yes there are somewhere in this globe 😅).. With the crazy growth of the Enterprise Development context thru Spring Boot/Cloud, Docker, Kubernetes and the unlimited number of JS frameworks, the infinite patterns and styles of architectures, many developers lost the frequency of being up-to-date with the upstream 🤪
I was one of the unsynchronized Java developers that couldn’t get up-to-date with all this crazy new comers everyday 🥺🤯 I got the idea to write a new post, to help Java developers get upToDate Quickly on the last five Java Releases 😁
⚠️⚠️ I will try to list the most significant new features. This listing is inclusive but not exhaustive. ⚠️⚠️
JEP 222: jshell: The Java Shell (Read-Eval-Print Loop)
The JShell API and tool will provide a way to interactively evaluate declarations, statements, and expressions of the Java programming language within the JShell state. The JShell state includes an evolving code and execution state. To facilitate rapid investigation and coding, statements and expressions need not occur within a method, and variables and method need not occur within a class.
jshell tool will be a command-line tool with features to ease interaction including: a history with editing, tab-completion, automatic addition of needed terminal semicolons, and configurable predefined imports and definitions.
JSR 376: Java Platform Module System (JSR 376)
This is the biggest new feature of Java 9.
The primary goals of this project are to:
- Make it easier for developers to construct and maintain libraries and large applications;
- Improve the security and maintainability of Java SE Platform Implementations in general, and the JDK in particular;
- Enable improved application performance;
- Enable the Java SE Platform, and the JDK, to scale down for use in small computing devices and dense cloud deployments.
To achieve these goals, the JCP designed and implemented a standard module system for the Java 9 and applied that system to the Platform itself and to its Reference Implementation, JDK 9. The module system is powerful enough to modularize the JDK and other large legacy code bases, yet is still approachable by all developers.
A Module is a group of Java classes and resources packaged together with a descriptor file called
For sure, this JSR cannot be covered in this quick post. There are many books dedicated for this huge new feature:
- The Java Module System - Manning
- Java 9 Modularity Revealed - Apress
- Java 9 Modularity - O’Reilly
- Modular Programming in Java 9 - Packtpub
Private methods in Interfaces
Since Java 8, we have a new feature: Functional Interface which is an interface class that contains only a single abstract (unimplemented) method. A functional interface can contain default public and static methods have an implementation, in addition to the single unimplemented method. Starting from Java 9, these methods can be private.
JEP 110: the new HTTP/2 Client
Java 9 comes with a brand new native HTTP client that supports HTTP/2 with backward compatibility with the previous versions of HTTP. With this new HTTP client, we will not need additional libraries to call a REST API:
The code listed here was updated after the release Java 11: my actual runtime 😁
Java 7 brought a new feature called Try-with-Resource statement which was a very useful feature for handling/closing a resource when an exception occurs. This Try-with-Resource statement got updated in Java 9 to be more simplified and less verbose. Let’s take this example:
The Java 7 version:
The Java 9 version:
JEP 102: Process API Updates
The Process API got also updated in Java 9: new classes and methods are introduced to ease the controlling and managing of OS processes.
For example, to show the current PID:
JEP 269: Convenience Factory Methods for Collections
Java 9 has introduced some convenient factory methods to create Immutable List, Set, Map and Map.Entry objects. These utility methods are used to create empty or non-empty Collection objects. Let’s take the example of creating an immutable List:
Before Java 9:
In Java 9:
Enhanced Optional class
The Optional class got some new methods in Java 9:
ifPresentOrElse(): If a value is present, performs the given action with the value, otherwise performs the given empty-based action.
or(): If a value is present, returns an Optional describing the value, otherwise returns an Optional produced by the supplying function.
stream(): If a value is present, returns a sequential
Streamcontaining only that value, otherwise returns an empty
Enhanced Stream API
In Java 9, we got four new methods to
takeWhile(): Returns, if this stream is ordered, a stream consisting of the longest prefix of elements taken from this stream that match the given predicate. Otherwise returns, if this stream is unordered, a stream consisting of a subset of elements taken from this stream that match the given predicate.
dropWhile(): Returns, if this stream is ordered, a stream consisting of the remaining elements of this stream after dropping the longest prefix of elements that match the given predicate. Otherwise returns, if this stream is unordered, a stream consisting of the remaining elements of this stream after dropping a subset of elements that match the given predicate.
ofNullable(): Returns a sequential Stream containing a single element, if non-null, otherwise returns an empty Stream.
iterate(): Returns a sequential ordered Stream produced by iterative application of the given next function to an initial element, conditioned on satisfying the given hasNext predicate. The stream terminates as soon as the hasNext predicate returns false.
For example: this code will show the numbers less than 50:
Enhanced Diamond operator
Java 9 improved the use of diamond operator and allows us to use the diamond operator with anonymous inner classes. Let’s take this example, which was not possible to run before Java 9:
JEP 266: More Concurrency Updates
Java 9 comes with some changes to the CompletableFuture class to solve some problems raised since its introduction in Java 8. Now, it supports delays and timeouts, and a better support for subclassing.
The new class methods:
CompletableFuture<T> completeAsync(Supplier<? extends T> supplier, Executor executor)
CompletableFuture<T> completeAsync(Supplier<? extends T> supplier)
CompletableFuture<T> orTimeout(long timeout, TimeUnit unit)
CompletableFuture<T> completeOnTimeout(T value, long timeout, TimeUnit unit)
The new static methods:
Executor delayedExecutor(long delay, TimeUnit unit, Executor executor)
Executor delayedExecutor(long delay, TimeUnit unit)
<U> CompletionStage<U> completedStage(U value)
<U> CompletionStage<U> failedStage(Throwable ex)
<U> CompletableFuture<U> failedFuture(Throwable ex)
JEP 286: Local-Variable Type Inference
Local-Variable Type Inference is the biggest new feature in Java 10 that many many developers are waiting for 🥳 It adds type inference to declarations of local variables with initializers. Now, we can do this in Java 😁
In this code:
numberswill be inferred as
numberwill be inferred as
letterswill be inferred as
letterwill be inferred as
Java Improvements for Docker Containers
Java 10 came with many new features to improve the execution and configurability of Java running in Docker containers. I covered this great feature in a dedicated blog post: Playing with the JVM inside Docker Containers.
JEP 304: Garbage-Collector Interface
Java 10 improves the source code isolation of different garbage collectors by introducing a clean garbage collector (GC) interface that helps:
- Better modularity for HotSpot internal GC code
- Make it simpler to add a new GC to HotSpot without perturbing the current code base
- Make it easier to exclude a GC from a JDK build
JEP 307: Parallel Full Garbage Collector for G1
Since Java 9, G1 garbage collector is the default garbage collector. The JEP 307 improves G1 worst-case latencies by making the full GC parallel. The G1 garbage collector is designed to avoid full collections, but when the concurrent collections can’t reclaim memory fast enough a fall back full GC will occur. The old implementation of the full GC for G1 used a single threaded mark-sweep-compact algorithm. With JEP 307 the full GC has been parallelized and now use the same amount of parallel worker threads as the young and mixed collections.
JEP 310: Application Class-Data Sharing
The goal of this feature is to improve the startup footprint, extends the existing Class-Data Sharing (“CDS”) feature to allow application classes to be placed in the shared archive.
Class-Data Sharing, introduced in JDK 5, allows a set of classes to be pre-processed into a shared archive file that can then be memory-mapped at runtime to reduce startup time. It can also reduce dynamic memory footprint when multiple JVMs share the same archive file.
Currently CDS only allows the bootstrap class loader to load archived classes. Application CDS allows the built-in system class loader, the built-in platform class loader, and custom class loaders to load archived classes.
-XX:+UseAppCDS command-line option to enable class data sharing for the system class loader, the platform class loader, and other user-defined class loaders.
JEP 312: Thread-Local Handshakes
This internal JVM feature aims to improve performance. A handshake operation is a callback that is executed for each JavaThread while that thread is in a safepoint state. The callback is executed either by the thread itself or by the VM thread while keeping the thread in a blocked state.
This feature provides a way to execute a callback on threads without performing a global VM safepoint. Make it both possible and cheap to stop individual threads and not just all threads or none.
JEP 313: Remove the Native-Header Generation Tool (javah)
javah has been removed from Java 10 which generated C headers and source files which were required to implement native methods – now,
javac -h can be used instead.
JEP 314: Additional Unicode Language-Tag Extensions
It’s goal is to enhance java.util.Locale and related APIs to implement additional Unicode extensions of BCP 47 language tags.
Support for BCP 47 language tags was was initially added in Java 7, with support for the Unicode locale extension limited to calendars and numbers. This JEP will implement more of the extensions specified in the latest LDML specification, in the relevant JDK classes.
This JEP will add support for the following additional extensions:
- cu (currency type)
- fw (first day of week)
- rg (region override)
- tz (time zone)
Related APIs which got modified are:
JEP 317: Experimental Java-Based JIT Compiler
This JEP will enable Graal: the Java-based Just-in-Time compiler, to be used as an experimental JIT compiler on the Linux/x64 platform.
Graal was introduced in Java 9. It’s an alternative to the JIT compiler which we have been used to, which was written in C++. It’s an addon to the JVM, which means that the JIT compiler is not tied to JVM and it can be dynamically plugged in and replaced with any another plugin. It also brings :
- Ahead of Time (AOT) compilation in Java Applications
- the support of polyglot language interpretation
JEP 319: Root Certificates
This JEP will open-source the root certificates in Oracle’s Java SE Root CA program in order to make OpenJDK builds more attractive to developers, and to reduce the differences between those builds and Oracle JDK builds. This means that both Oracle JDK & OpenJDK binaries will be functionally the same.
JEP 322: Time-Based Release Versioning
This JEP will revise the version-string scheme of the Java SE Platform and the JDK, and related versioning information, for present and future time-based release models. Especially that since Java 10, we intend to ship new releases of the Java SE Platform and the JDK on a strict, six-month cadence.
The new format will be:
The sequence may be of arbitrary length but the first four elements are assigned specific meanings, as follows:
$FEATURE— The feature-release counter, incremented for every feature release regardless of release content. Features may be added in a feature release; they may also be removed, if advance notice was given at least one feature release ahead of time. Incompatible changes may be made when justified. (Formerly
$INTERIM— The interim-release counter, incremented for non-feature releases that contain compatible bug fixes and enhancements but no incompatible changes, no feature removals, and no changes to standard APIs. (Formerly
$UPDATE— The update-release counter, incremented for compatible update releases that fix security issues, regressions, and bugs in newer features. (Formerly
$SECURITY, but with a non-trivial incrementation rule.)
$PATCH— The emergency patch-release counter, incremented only when it’s necessary to produce an emergency release to fix a critical issue. (Using an additional element for this purpose minimizes disruption to both developers and users of in-flight update releases.)
JEP 296: Consolidate the JDK Forest into a Single Repository
For many years, the full JDK code base has been splitted into numerous Mercurial repositories. In Java 9, there are eight repos:
The individual repos don’t have a development cycle separate from the JDK as a whole; all the repos advance in lockstep with the JDK promotion cycle. The multiplicity of repos presents a larger than necessary barrier to entry to new developers and has lead to workarounds such as the “get source” script.
Starting from Java 10, the numerous repositories of the JDK forest will be combined into a single repository in order to simplify the development.
JEP 330: Launch Single-File Source-Code Programs
One major change is that you don’t need to compile the java source file with
javac tool first. You can directly run the file with
java command and it will implicitly compile before running.
New String methods
Java 11 brings new methods in the String class:
lines(): Returns a stream of lines extracted from this string, separated by line terminators.
isBlank(): Returns true if the string is empty or contains only white spaces, otherwise false.
repeat(): Returns a string whose value is the concatenation of this string repeated count times.
strip(): Returns a string whose value is this string, with all leading and trailing
stripLeading(): Returns a string whose value is this string, with all leading
stripTrailing(): Returns a string whose value is this string, with all trailing
lines(): Returns a stream of lines extracted from this string, separated by line terminators.
JEP 323: Local-Variable Syntax for Lambda Parameters
This JEP allows the keyword
var to be used when declaring the formal parameters of implicitly typed lambda expressions. For example, we can do this in Java 11:
(var x, var y) -> x.process(y)
New methods added in java.nio.file.Files
Java 11 introduced new methods in the
readString(): Reads all content from a file into a string, decoding from bytes to characters.
writeString(): Write a CharSequence to a file.
isSameFile(): Tests if two paths locate the same file.
Working example using these new methods:
This sample code will have an output similar to:
File name: [file:///var/folders/0v/m4k0wtm521xfsmwyfr1_zslm0000gn/T/test303123248058134079.txt] File content: [Hello World] Are two tmp files equals? : false
New ToArray() method in the Collection Class
toArray(java.util.function.IntFunction): Returns an array containing all of the elements in this collection, using the provided generator function to allocate the returned array. For example:
New isEmpty() method in the Optional class
Optional.isEmpty() returns true if the value of any object is null and else returns false. This can be done in Java 11:
JEP 321: HTTP Client (Standard)
Java 11 has a native HTTP Client supporting WebSocket connections! The client was already introduced in Java 9. But in the Java 11, the HTTP Client API get standardized 🥳
Here is a Java 11 WebSocket example:
JEP 328: Flight Recorder
Flight Recorder is a profiling tool used to gather diagnostics and profiling data from a running Java application. Its performance overhead is negligible and that’s why it can be used in production.
Flight Recorder records events originating from applications, the JVM and the OS. Events are stored in a single file that can be attached to bug reports and examined by support engineers, allowing after-the-fact analysis of issues in the period leading up to a problem. Tools can use an API to extract information from recording files.
JEP 331: Low-Overhead Heap Profiling
This JEP provides a way to get information about Java object heap allocations from the JVM that:
- Is low-overhead enough to be enabled by default continuously
- Is accessible via a well-defined, programmatic interface
- Can sample all allocations
- Can be defined in an implementation-independent way (i.e., not limited to a particular GC algorithm or VM implementation)
- Can give information about both live and dead Java objects.
JEP 325: Switch Expressions (Preview)
I think this is the most important feature coming in Java 12. This is a preview feature that extends the
switch statement so that it can be used as either a statement or an expression. Let’s say what’s new:
- There is no need for
breakstatement - your case will not be falling into the next
- We can define multiple constants in the same label.
defaultcase is now compulsory in Switch Expressions.
breakis used in Switch Expressions to return values from a case itself.
These changes will simplify everyday coding 🤩 for example, instead of doing this before Java 12:
We can now do it in the easy way:
As it’s a preview feature, you will need to add
--enable-preview parameter to the
javac command in order to compile this code under JDK 12.
JEP 230: Microbenchmark Suite
This JEP adds a basic suite of microbenchmarks to the JDK source code, and make it easy to run existing microbenchmarks and create new ones. It is based on the Java Microbenchmark Harness (JMH).
Let’s test JMH; first of all, you can generate the sample project using the command:
This command will create a Maven project, containing only one class called
org.sample.MyBenchmark. We will use it to benchmark our code:
Now, compile the project using:
mvn clean install - this command will build two jars:
test-1.0.jar 👉 the compiled project
benchmarks.jar 👉 the JMH Jar file 😁 to run the benchmarking, run this jar using the
java -jar target/benchmarks.jarcommand.
The output of running the benchmarks:
WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by org.openjdk.jmh.util.Utils (file:/Users/nebrass/temp/test/target/benchmarks.jar) to field java.io.Console.cs WARNING: Please consider reporting this to the maintainers of org.openjdk.jmh.util.Utils WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations WARNING: All illegal access operations will be denied in a future release # JMH version: 1.22 ... # VM options: <none> # Warmup: 5 iterations, 10 s each # Measurement: 5 iterations, 10 s each # Timeout: 10 min per iteration # Threads: 1 thread, will synchronize iterations # Benchmark mode: Throughput, ops/time # Benchmark: org.sample.MyBenchmark.testMethod # Run progress: 0,00% complete, ETA 00:08:20 # Fork: 1 of 5 # Warmup Iteration 1: Enter your product number ... 80421,846 ops/s Result "org.sample.MyBenchmark.testMethod": 60122,841 ±(99.9%) 18195,223 ops/s [Average] (min, avg, max) = (21484,177, 60122,841, 82116,041), stdev = 24290,103 CI (99.9%): [41927,618, 78318,065] (assumes normal distribution) # Run complete. Total time: 00:08:22 REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial experiments, perform baseline and negative tests that provide experimental control, make sure the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts. Do not assume the numbers tell you what you want them to tell. Benchmark Mode Cnt Score Error Units MyBenchmark.testMethod thrpt 25 60122,841 ± 18195,223 ops/s
JEP 189: Shenandoah: A Low-Pause-Time Garbage Collector (Experimental)
This feature adds a new garbage collection (GC) algorithm named Shenandoah which reduces GC pause times by doing evacuation work concurrently with the running Java threads. Pause times with Shenandoah are independent of heap size, meaning you will have the same consistent pause times whether your heap is 200 MB or 200 GB.
New Teeing() method in Collectors Class
Java 12 introduces a new teeing collector in the Collectors class. This collector forwards its input to two other collectors before merging their results with a function.
JEP 341 Default CDS Archives
This JEP enhances the build process to generate a Class Data-Sharing (CDS) archive, using the default class list, on 64-bit platforms. This aims to improve startup time. From Java 12, CDS is by default ON.
JEP 344 : Abortable Mixed Collections for G1
This JEP bring improvements in G1 efficiency include making G1 mixed collections abortable if they might exceed the defined pause target. This is done by splitting the mixed collection set into mandatory and optional. Thus the G1 collector can prioritize on collecting the mandatory set first to meet the pause time goal.
New MISMATCH() method in the java.nio.files class
Based on the
javadoc: Finds and returns the position of the first mismatched byte in the content of two files, or
-1L if there is no mismatch. For example:
This code will output
Mismatch:  as the first different character between
"Hello World" and
"HelloWorld" will be on the 5th position.
JEP 305: Pattern Matching for instanceof (Preview)
This is a preview of a new feature. This JEP will enhance the Java programming language with pattern matching for the
instanceof operator. Pattern matching allows common logic in a program, namely the conditional extraction of components from objects, to be expressed more concisely and safely.
Before Java 12:
The new way is :
This will improve the readability of the code 😁
New methods in the String class
Java 12 introduced many new useful methods:
indent(): Adjusts the indentation of each line of this string based on the value of n, and normalizes line termination characters.
transform(): This method allows the application of a function to this string.
describeConstable(): Returns an Optional containing the nominal descriptor for this instance, which is the instance itself.
resolveConstantDesc(): Resolves this instance as a ConstantDesc, the result of which is the instance itself.
JEP 354: Switch Expressions (Preview)
Switch expressions were proposed in December 2017 by JEP 325. They were targeted to JDK 12 in August 2018 as a preview feature. Feedback was sought initially on the design of the feature, and later on the experience of using
switch expressions and the enhanced
switch statement. Based on that feedback, this JEP makes one change to the feature:
To yield a value from a
breakwith value statement is dropped in favor of a
This Java 12 code:
Can be written in Java 13 to be like:
⚠️⛔️⚠️⛔️ The Value Break is no more compilable in Java 13:
As it’s a preview feature, you will need to add
--enable-preview parameter to the
javac command in order to compile this code under JDK 13.
JEP 355: Text Blocks (Preview)
Add text blocks to the Java language. A text block is a multi-line string literal that avoids the need for most escape sequences, automatically formats the string in a predictable way, and gives the developer control over format when desired.
This feature will improve the readability of the code and will remove the Strings boilerplate that hurt the developers when dealing with multilines Strings.
This is a preview language feature in JDK 13, you will need to add
--enable-preview parameter to the
javac command in order to compile this code.
New Methods in THE String Class
There are three new methods in the String class that complement the Text Blocks feature:
formatted(): Formats using this string as the format string, and the supplied arguments.
stripIndent(): Returns a string whose value is this string, with incidental white space removed from the beginning and end of every line.
translateEscapes(): Returns a string whose value is this string, with escape sequences translated as if in a string literal.
New Factory methods in the FileSystems class
This JEP introduces three new methods in the FileSystems class to make it easier to use file system providers, which treats the contents of a file as a file system.
newFileSystem(Path path): Constructs a new FileSystem to access the contents of a file as a file system.
newFileSystem(Path path, Map<String,?> env): Constructs a new FileSystem to access the contents of a file as a file system.
newFileSystem(Path path, Map<String,?> env, ClassLoader loader): Constructs a new FileSystem to access the contents of a file as a file system.
JEP 353: Reimplement the Legacy Socket API
The underlying implementation of the
java.net.ServerSocket APIs have been rewritten. The new implementation,
NioSocketImpl, is a drop-in replacement for
java.util.concurrent locks rather than synchronized methods. If you want to use the legacy implementation, use the java option
JEP 350: Dynamic CDS Archives
This JEP enhanced the JEP 310 Application Class-Data Sharing which was introduced in Java 10, by simplifying the process of creating CDS archives.
The CDS archives will be created if the program exists with
To run the program with the CDS archives above:
The idea behind Class Data Sharing (CDS) is a feature to improve startup performance by creating class-data archive once and then reuse it, so that the JVM need not recreate it again.
JEP 351: ZGC: Uncommit Unused Memory
This JEP has enhanced ZGC to return unused heap memory to the operating system. The Z Garbage Collector was introduced in Java 11. It adds a short pause time before the heap memory cleanup. But, the unused memory was not being returned to the operating system. This was a concern for devices with small memory footprint such as IoT and microchips. Now, it has been enhanced to return the unused memory to the operating system.
As you see, Java is bringing a large number of new features and APIs. And it will continue to deliver incremental evolutions of the language, ensuring it remains the most popular and the most wonderful programming language on the planet 😍