Java Versions and Features

In this post, I will cover Java’s Long-Term Support (LTS) versions and features.

Java 8

Java 8 was released in 2014.

Lambda expressions

Lambda expression is a block of code that you can pass around so it can be executed later, once or multiple times. It can be seen as a brief version of instantiating a anonymous class of a functional interface (only have one abstract method).

Common functional interfaces

  • java.lang.Runnable
  • java.util.function.Function
  • java.util.function.Consumer

Example 1: Runnable interface

Using anonymous class

public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("hello");
}
}).start();
}

Using lambda expression

public static void main(String[] args) {
new Thread(() -> System.out.println("hello")).start();
}

Example 2: Function interface

public static void printGreetWithDifferentCase(Function<String, String> caseConverter) {
System.out.println(caseConverter.apply("Hello World"));
}

Using anonymous class

public static void main(String[] args) {
printGreetWithDifferentCase(new Function<String, String>() {
@Override
public String apply(String s) {
return s.toUpperCase();
}
});
}

Using lambda expression

public static void main(String[] args) {
printGreetWithDifferentCase(s -> s.toUpperCase());
}

Interfaces with default methods

Default methods enable you to add new functionality to the interfaces of your libraries and ensure binary compatibility with code written for older versions of those interfaces.

For example,

public class Test0423 {
interface A {
void methodA();
void methodB();
// All implementing classes can call this method without implementing it.
default void methodC() {
System.out.println("methodC");
}
}

static class B implements A {
@Override
public void methodA() {
}
@Override
public void methodB() {
}
}

public static void main(String[] args) {
B b = new B();
b.methodC();
}
}

Stream API

Streams and loops both operate on collections. But stream operations are more concise and powerful.

For example,

double average = users
.stream()
.filter(u -> u.getGender() == User.Sex.MALE)
.mapToInt(User::getAge)
.average()
.getAsDouble();

Optional Class

Reduces null checks and helps prevent NullPointerException.

String deptName = Optional.ofNullable(user)
.map(SysUser::getDept)
.map(SysDept::getDeptName)
.orElse("defaultDept");

Java 11

Java 11 was released in 2018. In this section, cover Java 9~11 features.

Modules

Since Java 9

Java 9 introduced a new system, called the Java Platform Module System, that is supported by the Java compiler and virtual machine. It was designed to modularize the large code base of the Java platform.

A module system provides the same benefits for programming in the large. A module can make classes and packages selectively available so that its evolution can be controlled.

Local variable type inference (var)

Since Java 10.

// Pre-Java 10
String name = "Thomas";

// With Java 10
var name = "Thomas"

HTTP client

Preview in Java 9. Standard Java 11.

With Java 11, Java got its own, modern client. It can be used to request HTTP resources over the network. It supports HTTP/1.1 and HTTP/2, both synchronous and asynchronous programming models, handles request and response bodies as reactive-streams

Example 1: A synchronous HTTP request

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://openjdk.org/"))
.build();
HttpResponse<String> resp = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());

Example 2: A asynchronous HTTP request

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://openjdk.org/"))
.build();
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();

JShell

JShell is an interactive tool introduced in Java 9 that allows for the execution of Java code snippets without the need for a full class structure.

Language and library enhancements

Java 9 enhancements

1. Collections

  • List.of()
  • Set.of()
  • Map.of()

2. Streams

  • takeWhile()
  • dropWhile()
  • iterate()

3. Optionals

  • ifPresentOrElse()

4. Interfaces

Interfaces got private methods.

public interface MyInterface {

private static void myPrivateMethod(){
System.out.println("I am a private method");
}
}

Java 11 enhancements

Strings

  • isBlank()
  • lines()
  • strip()

Files

  • writeString()
  • readString()

Java 17

Java 17 was released in 2021. In this section, cover Java 12~17 features.

Switch expressions

Preview in Java 12. Standard in Java 14.

Switch expressions can now return a value. And you can use a lambda-style syntax for your expressions, without the fall-through/break issues:

import static java.time.DayOfWeek.*;

public class Test {

public static void main(String[] args) {
var day = WEDNESDAY;
int numLetters = switch (day) {
case MONDAY, FRIDAY, SUNDAY -> 6;
case TUESDAY -> 7;
default -> {
String s = day.toString();
int result = s.length();
yield result;
}
};
System.out.println(numLetters);
}
}

Text blocks / Multiline Strings

Preview in Java 13. Standard in Java 15.

String htmlBeforeJava13 = "<html>\n" +
" <body>\n" +
" <p>Hello, world</p>\n" +
" </body>\n" +
"</html>\n";

String htmlWithJava13 = """
<html>
<body>
<p>Hello, world</p>
</body>
</html>
""";

instanceof pattern matching

Preview in Java 14. Standard in Java 16.

The old way

if (obj instanceof String) {
String s = (String) obj;
// use s
}

The new way

if (obj instanceof String s) {
System.out.println(s.contains("hello"));
}

Records

Preview in Java 14.

The old way

final class Point {
public final int x;
public final int y;

public Point(int x, int y) {
this.x = x;
this.y = y;
}
}

The new way

record Point(int x, int y) {
// Constructor, getters, and other methods are automatically generated
// by the compiler for record classes.
}

Sealed classes

Preview in Java 15. Standard in Java 17.

Specify what classes can subclass current class.

public sealed class A permits B, C {

}

For example,

public abstract sealed class Shape 
permits Circle, Rectangle, Square {
}

Java 21

Java 21 was released in 2023. In this section, cover Java 18~21 features.

Virtual threads (Project Loom)

Virtual threads are lightweight threads that reduce the effort of writing, maintaining, and debugging high-throughput concurrent applications.

Like a platform thread, a virtual thread is also an instance of java.lang.Thread. However, a virtual thread isn’t tied to a specific OS thread. A virtual thread still runs code on an OS thread. However, when code running in a virtual thread calls a blocking I/O operation, the Java runtime suspends the virtual thread until it can be resumed. The OS thread associated with the suspended virtual thread is now free to perform operations for other virtual threads.

Thread thread = Thread.ofVirtual()
.start(() -> System.out.println("Hello"));
thread.join();

Pattern matching for Switch

Adds a more expressive and safer switch.

References

[1] Core Java (13th, 2024)

[2] Java Versions and Features

[3] Java 8 vs Java 11 vs Java 17 vs Java 21: A Comprehensive Comparison