1. Introduction
Java 21 introduced one of the most useful enhancements for developers working with pattern matching and variable declarations: Unnamed Patterns and Unnamed Variables. These features help eliminate unused variables, reduce boilerplate, and make code more readable. Instead of assigning names to variables you never use, Java now lets you replace them with an underscore (_).
This article explains why these features exist, how they solve real problems, and how to implement them in modern Java code. A detailed real-life scenario is also provided to make the concept easy to understand.
2. The Problem
When working with pattern matching, records, switch expressions, and destructuring logic, developers often end up extracting values they simply do not use. Before Java 21, developers often wrote code like:
if (obj instanceof UserRecord(String name, int age, String address)) {
System.out.println("Name: " + name);
}If only the name field is needed, the extra unused variables (age and address) still had to be declared, causing unnecessary clutter and warnings. This reduced clarity and added cognitive load for maintainers.
Java 21 solves this through Unnamed Patterns and Unnamed Variables.
3. The Solution
3.1 Unnamed Variable: _
Use _ when a variable must exist syntactically but will not be used. These are often applied in pattern matching or lambda expressions.
var (_, age) -> System.out.println(age);3.2 Unnamed Pattern: _ in Pattern Matching
Use _ inside pattern matching expressions to ignore fields of records or sealed classes:
if (obj instanceof UserRecord(String name, _)) {
System.out.println(name);
}This allows matching the structure without binding unwanted values.
4. Implementation
Below is a real-life implementation using a notification processing system. Each notification type has several fields, but only one or two matter for logging or routing.
Real-Life Scenario: Processing Notification Types
Suppose a system receives different types of notifications:
- EmailNotification(sender, subject, body)
- SMSNotification(sender, message)
- PushNotification(deviceId, title, body, metadata)
Only the main identifier (sender or deviceId) is required. Java 21 allows ignoring the rest.
4.1 Defining Sealed Interfaces and Records
sealed interface Notification
permits EmailNotification, SMSNotification, PushNotification {}
record EmailNotification(String sender, String subject, String body) implements Notification {}
record SMSNotification(String sender, String message) implements Notification {}
record PushNotification(String deviceId, String title, String body, Map<String, Object> metadata) implements Notification {}4.2 Without Unnamed Patterns (Pre-Java 21)
void process(Notification notification) {
switch (notification) {
case EmailNotification(String sender, String subject, String body) ->
System.out.println("Email from: " + sender);
case SMSNotification(String sender, String message) ->
System.out.println("SMS from: " + sender);
case PushNotification(String deviceId, String title, String body, Map<String, Object> metadata) ->
System.out.println("Push notification on: " + deviceId);
}
}This creates variables that are never used (subject, body, metadata).
4.3 With Unnamed Patterns (Java 21)
void process(Notification notification) {
switch (notification) {
case EmailNotification(String sender, _, _) ->
System.out.println("Email from: " + sender);
case SMSNotification(String sender, _) ->
System.out.println("SMS from: " + sender);
case PushNotification(String deviceId, _, _, _) ->
System.out.println("Push notification on: " + deviceId);
}
}The code is now cleaner, easier to maintain, and free of unnecessary variable references.
4.4 Unnamed Variables in Lambda Expressions
notifications.forEach((_, n) -> System.out.println("Processing: " + n));metadata.forEach((_, value) -> System.out.println(value));5. Conclusion
Java 21 provides a powerful improvement for writing cleaner code using Unnamed Patterns and Unnamed Variables. These features help developers eliminate unnecessary variables, simplify pattern matching, and reduce boilerplate. If you are upgrading to Java 21, incorporating these features will help make your applications more readable and maintainable.