Intro

JEP 455 is yet another feature delivered in Java 23. It aims to improve further the convenience of usage of primitive types. In a nutshell this JEP enhances usage of primitive types in switch and instance of as well as in pattern matching context. Let’s take a deeper look at his enhancements.

How it was before

Before java 23 we have limited capabilities when using primitive types in our code base:

  • decomposition of records would not allow primitive type narrowing, e.g. entity instanceof Person(int salary) was not allowed if class Person has property salary of type primitive type double, only strict following of type is allowed entity instanceof Person(double salary)
  • instanceof did not support primitive types:
    • we could not use instanceof operator to check the type of a variable if it was of a primitive type, because instanceof allows only reference types, e.g. i instanceof byte would not work
    • pattern matching for primitive types was not allowed, e.g. instanceof float salary
  • switch did not support primitive types:
    • boolean, float, double, or long. Only byte, short, char, and int were permitted so far
    • pattern matching in switch for primitive type could not be used at all, e.g. case like case int i

Changes java 23 brings with JEP 455

Now we can use pattern matching on primitives in switch and result of pattern matching can be used in guard.

switch (x.getYearlyFlights()) {
    case 0 -> ...;
    case 1 -> ...;
    case 2 -> issueDiscount();
    case int i when i >= 100 -> issueGoldCard();
    case int i -> ... appropriate action when i > 2 && i < 100 ...
}

In switch we can now use all primitive types and not only a subset. For example, we can replace if else statement with much more convenient switch expression like this:

switch (user.isLoggedIn()) {
    case true  -> user.id();
    case false -> { log("Unrecognized user"); yield -1; }
}

In instanceof we can use primitive types and pattern matching with primitive types:

if (i instanceof byte b) {
    ... b ...
}

When using pattern matching with Records we don’t need to use exact type of property, if it is possible to safely convert one type into another, instanceof will not only return true, but also will create a named variable of converted property.

record Person(double salary) {}
...
entity instanceof Person(int s)

Conclusion

Pattern matching and enhancements of instanceof and switch can save us from writing boiler plate code and make reading of a program much smoother.

Source info

Updated: