Java 17 APIs & Features

Java 17 represents a major Long-Term Support release that brings sealed classes to production readiness and introduces powerful pattern matching capabilities. This LTS version focuses on language improvements, enhanced random number generation, and platform modernization while providing extended support for enterprise applications.

Released: September 2021
Long-Term Support (LTS)
Long-Term Support

Java 17 Overview

Release Information

Release Date:

September 2021

Support Type:
Long-Term Support (LTS)

Quick Summary

Java 17 represents a major Long-Term Support release that brings sealed classes to production readiness and introduces powerful pattern matching capabilities. This LTS version focuses on language improvements, enhanced random number generation, and platform modernization while providing extended support for enterprise applications.

Top Features

  • Sealed Classes (Standard) - Production-ready class hierarchy control
  • Pattern Matching for switch (Preview) - Enhanced switch expressions with patterns
  • Enhanced Pseudo-Random Number Generators - Improved random number generation algorithms
  • Strongly Encapsulated JDK Internals - Better security and maintainability
  • New macOS rendering pipeline - Improved graphics performance on macOS
  • Deprecation of Applet API - Modernization of the Java platform

API Examples

Enhanced Random Number Generators

Java 17 introduces enhanced pseudo-random number generators with new interfaces and algorithms that provide better performance, improved statistical quality, and support for parallel processing. This feature enables developers to choose appropriate random number generation algorithms for different use cases, from cryptographic applications to simulations and games.

import java.util.random.RandomGenerator;
import java.util.random.RandomGeneratorFactory;

// Using the new RandomGenerator interface
RandomGenerator random = RandomGenerator.getDefault();
int randomInt = random.nextInt(1, 101); // Random int between 1-100

// Explore available algorithms
RandomGeneratorFactory.all()
    .map(RandomGeneratorFactory::name)
    .forEach(System.out::println);

// Use specific algorithm
RandomGenerator xoroshiro = RandomGeneratorFactory
    .of("Xoroshiro128PlusPlus")
    .create();

// Jump ahead in the sequence (for parallel processing)
RandomGenerator jumped = xoroshiro.jump();

// Generate random stream
random.ints(10, 1, 100)
    .forEach(System.out::println);

// Generate random doubles
random.doubles(5, 0.0, 1.0)
    .forEach(System.out::println);

Pattern Matching for switch (Preview)

Java 17 introduces pattern matching for switch statements as a preview feature, enabling more expressive and type-safe switch expressions. This feature allows developers to use patterns in switch cases, making code more readable and eliminating the need for multiple if-else statements while providing compile-time safety guarantees.

// Traditional approach
public String formatObject(Object obj) {
    if (obj instanceof String) {
        return "String: " + obj;
    } else if (obj instanceof Integer) {
        return "Integer: " + obj;
    } else if (obj instanceof Double) {
        return "Double: " + obj;
    } else {
        return "Unknown type";
    }
}

// Pattern matching for switch (Java 17 preview)
public String formatObject(Object obj) {
    return switch (obj) {
        case String s -> "String: " + s;
        case Integer i -> "Integer: " + i;
        case Double d -> "Double: " + d;
        case null -> "null value";
        default -> "Unknown type";
    };
}

// With guards
public String describe(Object obj) {
    return switch (obj) {
        case String s when s.length() > 10 -> "Long string: " + s;
        case String s -> "Short string: " + s;
        case Integer i when i > 0 -> "Positive integer: " + i;
        case Integer i -> "Non-positive integer: " + i;
        default -> "Other type";
    };
}

Sealed Classes (Standard)

Java 17 standardizes sealed classes, providing fine-grained control over class hierarchies by allowing developers to specify which classes can extend or implement a sealed class. This feature improves code maintainability, enables better domain modeling, and supports exhaustive pattern matching by ensuring all possible subtypes are known at compile time.

// Define sealed class hierarchy
public sealed abstract class Shape 
    permits Circle, Rectangle, Triangle {
    
    public abstract double area();
}

// Permitted subclasses
public final class Circle extends Shape {
    private final double radius;
    
    public Circle(double radius) {
        this.radius = radius;
    }
    
    @Override
    public double area() {
        return Math.PI * radius * radius;
    }
}

public final class Rectangle extends Shape {
    private final double width, height;
    
    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }
    
    @Override
    public double area() {
        return width * height;
    }
}

public final class Triangle extends Shape {
    private final double base, height;
    
    public Triangle(double base, double height) {
        this.base = base;
        this.height = height;
    }
    
    @Override
    public double area() {
        return 0.5 * base * height;
    }
}

// Exhaustive pattern matching
public String describeShape(Shape shape) {
    return switch (shape) {
        case Circle c -> "Circle with area: " + c.area();
        case Rectangle r -> "Rectangle with area: " + r.area();
        case Triangle t -> "Triangle with area: " + t.area();
        // No default needed - compiler knows all possibilities
    };
}