JAVA-RELEASE/JAVA-11

Java 11 [LTS]: Features and Highlights

This article covers features of Java 11 with code examples

Pravinkumar Singh
Javarevisited
Published in
7 min readJun 15, 2023

--

image by @iampravo

Java 11, this was significant milestone in the evolution of Java 😲 and became a benchmark for Java developers. IT companies have begun to prefer hiring Java 11 developers 🌟. Released in September 2018, Java 11 came with improvements focused on productivity, security, and performance to enhance the overall Java experience for software engineers. In this article, we’ll dive into Java 11’s features, and illustrate scenarios using code examples.

8 out of 18 Notable Features and Improvements in Java 11

  1. Running Java files directly: Enhancements to java launcher allowing direct execution of single-file Java source code without explicit compilation.
  2. Improved var handling: Improved type inference for lambda expressions using var.
  3. HTTP Client API: The introduction of a standard HTTP Client API supporting HTTP/1.1, HTTP/2, and WebSocket communication.
  4. String Functions: New utility methods added to the String class, such as repeat(), isBlank(), strip(), lines().
  5. New Epsilon Garbage Collector: A no-op garbage collector to test the performance of applications.
  6. Java Flight Recorder (JFR) Event Streaming: The JFR now supports event streaming, providing more capabilities for monitoring and profiling Java applications.
  7. Eliminating Nashorn JavaScript Engine: The removal of the Nashorn JavaScript engine and associated API, making it unavailable for further use.
  8. TLS 1.3 Support: The implementation of TLS 1.3, improves the transport security of Java applications.

Running Java Files Directly (JEP 330)

In Java 11, you can now run a single-file Java source code using the java launcher without having to explicitly compile it. This feature simplifies the execution of small Java programs, allowing engineers to quickly write and test ideas.

Consider the following simple example, saved in a file named HelloWorld.java:

public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, world!");
}
}

-- Now run the Java file by executing the following command:
java HelloWorld.java

-- The output:
Hello, world!

With Java 11, there’s no need to compile the code with javac before executing it using java. This feature does not replace build systems for larger projects, but it streamlines the execution of small programs and simplifies experimentation with Java code.

Improved var Handling (JEP 323)

In Java 10, the var keyword was introduced for local variable type inference to make writing and reading code easier. Java 11 enhances the use of var, allowing it in lambda expressions. This feature simplifies lambda expressions while maintaining readability.

Consider the following code snippet:

// Pre-Java 11
Function<String, Integer> preJava11Func = (String s) -> Integer.parseInt(s) + 10;

// Java 11
Function<String, Integer> java11Func = (var s) -> Integer.parseInt(s) + 10;

In Java 11, we can replace the explicit String parameter type in the lambda expression with var..

HTTP Client API (JEP 321)

Java 11 introduces a new HTTP Client API to replace the older HttpURLConnection and provide a more modern, convenient way to access HTTP resources. The new API supports HTTP/1.1, HTTP/2, and WebSocket communication and can handle request and response bodies using the reactive-streams API.

Here’s an example illustrating the use of the new HTTP Client API:

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class HttpClientDemo {
public static void main(String[] args) throws Exception {
HttpClient httpClient = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/data"))
.GET()
.build();

HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

System.out.println(response.statusCode());
System.out.println(response.body());
}
}

In the example above, we create HttpClient, build HttpRequest, execute the request, and receive HttpResponse. This new API offers a more streamlined and efficient approach to handling HTTP communication.

New Utility Methods for String

Java 11 introduces several new utility methods for the String class, making working with strings more convenient:

  1. isBlank(): Checks if a string is empty or contains only white space characters.
String nonBlank = "Hello, world!";
boolean isNonBlank = nonBlank.isBlank(); // false

String blank = " \t ";
boolean isBlank = blank.isBlank(); // true

2. strip(), stripLeading(), and stripTrailing: Strips leading and/or trailing white spaces from a string, including Unicode white space characters beyond the ASCII space character.

String text = "   Java 11   ";

String stripped = text.strip(); // "Java 11"
String leadingStripped = text.stripLeading(); // "Java 11 "
String trailingStripped = text.stripTrailing(); // " Java 11"

3. lines(): Returns a stream of lines extracted from the given string, separated by line terminators.

String multilineText = "Line 1\nLine 2\nLine 3";

multilineText.lines().forEach(System.out::println);

4. repeat(int): Repeats the string the specified number of times.

String repeatedText = "ABC".repeat(3); // "ABCABCABC"

New Epsilon Garbage Collector (JEP 318)

Java 11 introduces the Epsilon Garbage Collector (GC), which is an experimental no-op garbage collector. Epsilon GC does not reclaim memory, allowing developers to assess application performance without garbage collection interference. While this is not a practical garbage collector for long-running applications, it’s helpful when testing application performance and determining the impact of GC algorithms on the application.

To use Epsilon GC when running a Java application, pass the following JVM option:

-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC

This setting can be useful for performance testing purposes, but should not be used for production applications.

Java Flight Recorder (JFR) Event Streaming (JEP 328)

Java 11 adds streaming capabilities to the Java Flight Recorder (JFR), a profiling and event collection framework. This feature allows developers to access data during application execution, enabling more robust monitoring and profiling of Java applications.

Here’s an example of using JFR event streaming:

import jdk.jfr.consumer.RecordingStream;

public class JFREventStreaming {
public static void main(String[] args) {
try (var rs = new RecordingStream()) {
rs.onEvent("jdk.GarbageCollection", event ->
System.out.format("Garbage collection: %s, duration: %dns%n", event.getEndTime(), event.getDuration())
);

rs.startAsync();
Thread.sleep(60_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

In this example, we create a RecordingStream, define an event handler for garbage collection events, start the stream asynchronously, and keep the application alive for 60 seconds to observe the events.

Eliminating Nashorn JavaScript Engine (JEP 335)

Java 11 removes the Nashorn JavaScript engine and the associated API. This removal means Nashorn scripts, tools, and libraries will no longer be available in Java 11 and future versions. Engineers should seek alternatives, such as GraalVM, to integrate with JavaScript or execute JavaScript code in a Java application.

TLS 1.3 Support (JEP 332)

Java 11 introduces support for TLS 1.3, the latest version of the Transport Layer Security (TLS) protocol. This support enhances the security and performance of Java applications in encrypted communication, benefiting HTTPS, as well as other secure connections. To use TLS 1.3 support in Java 11, ensure the server and client configuration have the protocol enabled.

Nest-Based Access Control (JEP 181)

This feature enhances access control in the Java language to align it with the use of the nest attribute in Java Virtual Machine (JVM). It improves the readability of code, and in many cases eliminates the need for compilers to insert accessibility-broadening bridge methods.

public class Outer {
private int x = 10;

class Inner {
public void printValue() {
System.out.println(x); // Can access private field of outer class
}
}
}

Dynamic Class-File Constants (JEP 309)

This feature extends the Java class-file format to support a new constant-pool form, CONSTANT_Dynamic. The goal is to reduce the cost and disruption of creating new forms of materializable class-file constants. This facilitates the creation of such constants for language designers and compiler implementors.

Improve Aarch64 Intrinsics (JEP 315)

This JEP aimed to improve the existing string and array intrinsics and implement new intrinsics for the AArch64 architecture, enhancing the efficiency of Java on the ARM-64 platform.

Remove the Java EE and CORBA Modules (JEP 320)

Java 11 removed the Java EE and CORBA modules from the Java SE Platform and the JDK. These modules were already deprecated in Java 9 with the declared intent to remove them in a future release. Consequently, applications that use these modules might need to migrate to alternative libraries.

Key Agreement with Curve25519 and Curve448 (JEP 324)

Java 11 brings new key agreement schemes using Curve25519 and Curve448 as described in RFC 7748. They are public-key cryptographic primitives, enhancing the security protocol.

Unicode 10 Support (JEP 327)

Java has been at the forefront when it comes to Internationalization. Keeping pace with evolving text representation standards, Java 11 integrates support for Unicode 10. This feature ensures Java applications accommodate newly defined emojis and other non-character symbols across different languages.

ChaCha20 and Poly1305 Encryptions (JEP 329)

Bringing modern cryptographic primitives, Java 11 introduces implementations for the ChaCha20 and ChaCha20-Poly1305 ciphers as specified in RFC 7539.

import javax.crypto.Cipher;
import javax.crypto.spec.ChaCha20ParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.GeneralSecurityException;

public class Encryption {
public static void main(String[] args) throws GeneralSecurityException {
Cipher cipher = Cipher.getInstance("ChaCha20-Poly1305/None/NoPadding");
byte[] keyBytes = new byte[32]; // Must be 256 bits for ChaCha20
byte[] nonceBytes = new byte[12]; // Must be 96 bits for ChaCha20
SecretKeySpec key = new SecretKeySpec(keyBytes, "ChaCha20");
ChaCha20ParameterSpec paramSpec = new ChaCha20ParameterSpec(nonceBytes);
cipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
}
}

Low-Overhead Heap Profiling (JEP 331)

This feature provides a mechanism to generate detailed heap information about applications’ memory allocations without imposing a significant performance penalty. It aids developers in understanding and debugging an application’s memory usage.

Z Garbage Collector (JEP 333)

ZGC is a new garbage collector introduced as an experimental feature in Java 11. Its primary goals are to handle heaps ranging from a few hundred megabytes to multi-terabytes in size with low latency.

To enable ZGC, you can use the command: `java -XX:+UnlockExperimentalVMOptions

java -XX:+UnlockExperimentalVMOptions -XX:+UseZGC MyClass

Please note that ZGC is an experimental feature and not intended for production

Deprecate the Pack200 Tools and API (JEP 336)

Java 11 deprecated the pack200 and unpack200 tools, and the Pack200 API in java.util.jar.Pack200. These have been removed completely in Java 14. Future JAR files will rely entirely on more modern compression techniques.

// Warns deprecation
java.util.jar.Pack200.Packer packer = java.util.jar.Pack200.newPacker();

Hope you found these features informative and helpful for your development 👨‍💻.

Peace! ✌️

Related reads : java-release

--

--