How Java 26 Primitive Type Pattern Matching Works
Problem
I have code that processes different types of values. Pattern matching works great for objects, but primitive types require boxing:
Object value = 42;
// Must match wrapper type, then unboxif (value instanceof Integer i) { int result = i * 2; // Unboxing happens here System.out.println(result);}
// Same problem in switchswitch (value) { case Integer i -> processInt(i); // i is Integer, not int case Double d -> processDouble(d); // d is Double, not double default -> processOther(value);}Boxing creates objects. Unboxing extracts primitives. Both add overhead for simple type checks.
Environment
- Java 26 (non-LTS)
--enable-previewrequired- Pattern matching scenarios
What Is Primitive Type Pattern Matching?
JEP 530 is the fourth preview of primitive types in patterns. It lets instanceof and switch work directly with primitive types.
Object value = 42;
// Match primitive int directlyif (value instanceof int i) { int result = i * 2; // No boxing! System.out.println(result);}
// Switch with primitive patternsswitch (value) { case int i -> processInt(i); // i is int, not Integer case double d -> processDouble(d); // d is double, not Double case long l -> processLong(l); // l is long, not Long default -> processOther(value);}No wrapper objects. No boxing. No unboxing. The pattern binds directly to the primitive value.
How It Works
Traditional Boxing:┌─────────┐ ┌──────────┐ ┌─────────┐│ int 42 │ → │ Integer │ → │ Match │└─────────┘ └──────────┘ └─────────┘ (object allocation)
Primitive Pattern:┌─────────┐ ┌─────────┐│ int 42 │ → │ Match │└─────────┘ └─────────┘ (no allocation)The JVM checks the type and extracts the primitive in one step.
Practical Example
Here’s a more complete example showing various primitive patterns:
public class PrimitivePatternExample { public static void main(String[] args) { Object[] values = {42, 3.14, 100L, "hello", true};
for (Object value : values) { String description = describe(value); System.out.println(value + " -> " + description); } }
static String describe(Object value) { return switch (value) { case int i -> "int: " + i + " (doubled: " + (i * 2) + ")"; case double d -> "double: " + d + " (squared: " + (d * d) + ")"; case long l -> "long: " + l; case boolean b -> "boolean: " + b; case String s -> "String: " + s; default -> "Unknown type"; }; }}Output:
42 -> int: 42 (doubled: 84)3.14 -> double: 3.14 (squared: 9.8596)100 -> long: 100hello -> String: hellotrue -> boolean: trueWhy Fourth Preview?
Each preview refines the feature:
| Version | Focus |
|---|---|
| JDK 23 | Initial preview |
| JDK 24 | Refined matching rules |
| JDK 25 | Edge case handling |
| JDK 26 | Stricter dominance checking in switch |
Dominance checking means the compiler catches cases that would never match:
switch (value) { case int i -> System.out.println("int"); case byte b -> System.out.println("byte"); // Error: dominated! // byte values always match int first}The compiler now warns about these unreachable patterns.
How to Enable
Primitive patterns are a preview feature. Enable them:
javac --enable-preview --release 26 PrimitivePatternExample.javajava --enable-preview PrimitivePatternExampleProduction use requires waiting for the feature to exit preview status.
When to Use
Good scenarios:
- Processing mixed-type collections
- Type-safe parsing and validation
- Data transformation pipelines
- Cleaner conditional logic
Benefits:
- No boxing overhead
- More expressive code
- Consistent pattern matching across all types
- Better performance for numeric operations
Summary
In this post, I showed how Java 26’s primitive type pattern matching works. The key points are:
instanceofandswitchcan now match primitive types directly- No boxing/unboxing overhead
- Fourth preview with refined dominance checking
- Enable with
--enable-preview - Wait for non-preview status before production use
Primitive patterns unify Java’s type system in pattern contexts. When they finalize, they’ll make type-safe code cleaner and more efficient.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
- 👨💻 JEP 530: Primitive Types in Patterns
- 👨💻 JEP 394: Pattern Matching for instanceof
- 👨💻 Oracle Java 26 Release
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments