Modern Java

111. Primitive Types in Patterns, instanceof, and switch

Java 23 expands pattern matching to all primitive types, permitting instanceof int, primitive deconstruction, and type-safe range matching in switch.

Java 23+ (JEP 455 Preview)

Explanation

Historically, pattern matching and instanceof in Java were restricted strictly to reference types. If you wanted to inspect whether a generic Number could safely fit into a byte, you had to check bounds manually or risk silent arithmetic overflow and precision truncation.

JEP 455 (Java 23) extends pattern matching to primitive types. It enables: 1. Primitive instanceof: Tests if a value can be converted to the target primitive type without loss of data or precision. For instance, num instanceof byte b checks both type and whether the numeric magnitude fits into [-128, 127]. 2. Primitive pattern switch: Direct switching on long, float, double, and boolean with pattern and guard expressions. 3. Record deconstruction with primitive conversions: Unpack record fields with widening or exact primitive patterns.

Example

// Enabled with preview flags in Java 23+
public class PrimitivePatternsDemo {
    public static void evaluateNumber(Number n) {
        // Safe narrowing pattern matching without overflow!
        switch (n) {
            case Byte b   -> System.out.println("Fits in Byte: " + b);
            case Short s  -> System.out.println("Fits in Short: " + s);
            case Integer i -> System.out.println("Standard Integer: " + i);
            case Long l   -> System.out.println("Wide Long: " + l);
            case Double d -> System.out.println("Floating double: " + d);
            default       -> System.out.println("Other number: " + n);
        }
    }

    public static void formatValue(Object obj) {
        // Primitive instanceof checks exact conversion safety
        if (obj instanceof int i) {
            System.out.println("Exact integer: " + i);
        } else if (obj instanceof double d) {
            System.out.println("Floating point: " + d);
        }
    }

    public static void main(String[] args) {
        evaluateNumber((byte) 42);
        evaluateNumber(1_000_000);
        formatValue(99);
    }
}

Sources