JEP 455, Primitive Types in Patterns, instanceof, and switch (Preview), has been promoted from Proposed to Target to Targeted for JDK 23. This JEP, under the auspices of Project Amber, proposes to enhance pattern matching by allowing primitive type patterns in all pattern contexts, and extend instanceof
and switch
to work with all primitive types. Aggelos Biboudis, principal member of technical staff at Oracle, has recently published an updated draft specification for this feature.
This proposal allows developers to directly test and convert between different primitive types, such as int
, byte
, and float
, without the verbose syntax traditionally required for such operations. For instance, with JEP 455, a check and cast that would previously require manual range checking and explicit casting can now be simplified.
Consider the following example:
if (i >= -128 && i <= 127) {
byte b = (byte)i;
... b ...
}
With this JEP, the above code snippets now can be simplified as follows:
if (i instanceof byte b) {
... b ...
}
This enhancement not only makes the code more readable but also significantly reduces the likelihood of errors related to lossy conversions.
This allows switch
expressions to process primitive type patterns directly, improving code clarity and expressiveness. For example, transforming a switch
statement to use primitive type patterns could simplify default clauses and enable guards to inspect matched values more efficiently. Consider the following example:
switch (x.getStatus()) {
case 0 -> System.out.println("OK");
case 1 -> System.out.println("Warning");
case 2 -> System.out.println("Error");
case int i -> System.out.println("Unknown status: " + i);
}
JEP 455 also addresses limitations related to record patterns and their interaction with primitive types. Previously, record patterns had constrained support for primitive types, necessitating explicit type declarations and potentially lossy conversions. The new enhancements allow for more flexible decompositions of records, facilitating the automatic narrowing of types without losing information, as shown in the following example:
if (json instanceof JsonObject(var map)
&& map.get("name") instanceof JsonString(String n)
&& map.get("age") instanceof JsonNumber(double a)) {
int age = (int)a; // More straightforward handling with JEP 455
}
Furthermore, the update seeks to rectify the exclusion of primitive type patterns in the pattern matching for instanceof
and switch
, which had limited Java's expressiveness. By incorporating primitive types into these constructs, developers can now perform more nuanced and safe type checks, reducing the risk of information loss during conversions. This enhancement is particularly useful when precise type control is crucial, such as handling numerical data or implementing complex control flow logic based on variable types.
JEP 455 does not aim to introduce new kinds of conversions between types, but rather to make the existing mechanisms more robust and inclusive. This approach ensures that the enhancements integrate smoothly with Java's existing type system, avoiding the introduction of unnecessary complexity or potential sources of error.
In conclusion, JEP 455 represents a significant step forward in Java's evolution, enhancing the language's pattern-matching capabilities by integrating primitive type patterns into all relevant contexts. This update not only simplifies the syntax for working with different types of data, but also aligns Java's type-checking mechanisms more closely, fostering a more intuitive and efficient development experience.