Java 25 introduces improvements such as record patterns with instanceof, which allow more concise and expressive type matching and data extraction in one step. Here’s a guide on how to use them:
What are record patterns?
A record pattern enables matching and extracting components of a record class, which is essentially a class with immutable data. Record patterns simplify operations by combining type checking and field extraction syntactically.
Using instanceof with Record Patterns
In Java 25, you can use a record pattern directly with instanceof to both:
1. Match the type of the object.
2. Decompose its contents in a single expression.
Example of Record Patterns with instanceof
record Point(int x, int y) {}
public class Main {
public static void main(String[] args) {
Object obj = new Point(10, 20);
// Using instanceof with a record pattern
if (obj instanceof Point(int x, int y)) {
System.out.println("Point coordinates: x = " + x + ", y = " + y);
} else {
System.out.println("Not a Point object");
}
}
}
Explanation
obj instanceof Point(int x, int y):- Pattern Matching: Verifies if
objis an instance of thePointrecord. - Decomposition: Extracts the
xandyfields of the record into variablesxandy.
- Pattern Matching: Verifies if
As a result:
- If
objmatches the type, the fields are extracted automatically in the same step. - There’s no need to cast
objtoPointexplicitly or manually call getters.
Nesting Record Patterns
Record patterns can also be nested for more complex records containing other records or collections.
Example: Nested Record Patterns
record Rectangle(Point topLeft, Point bottomRight) {}
public class Main {
public static void main(String[] args) {
Object obj = new Rectangle(new Point(0, 0), new Point(10, 10));
if (obj instanceof Rectangle(Point(int x1, int y1), Point(int x2, int y2))) {
System.out.println("Rectangle corners: (" + x1 + ", " + y1 + ") to (" + x2 + ", " + y2 + ")");
} else {
System.out.println("Not a Rectangle object");
}
}
}
Explanation
Rectangle(Point(int x1, int y1), Point(int x2, int y2))is a nested pattern:- Matches top-level
Rectangle. - Decomposes its
topLeftandbottomRightfields intoPointobjects. - Further extracts
xandycoordinates from eachPoint.
- Matches top-level
Benefits
- Conciseness: Eliminates the need for explicit casting or redundant getter calls.
- Readability: Patterns declaratively show what is being matched and extracted.
- Flexibility: Works seamlessly with nested structures.
Good-to-Know Details
- Exhaustive Matching: Combine
switchwith record patterns for exhaustive, cleaner matching:void printShapeInfo(Object shape) { switch (shape) { case Point(int x, int y) -> System.out.println("Point: (" + x + ", " + y + ")"); case Rectangle(Point topLeft, Point bottomRight) -> System.out.println("Rectangle with corners: " + topLeft + " to " + bottomRight); default -> System.out.println("Unknown shape"); } } - Null Handling:
instanceofwith patterns doesn’t match null values directly. An explicit null check is still required. -
Restrictions: The immutability of records ensures safety and predictability when decomposing data and matching patterns.
Conclusion
The introduction of record patterns in Java 25 significantly enhances pattern matching and makes working with immutable objects far more intuitive and concise. Whether you’re matching simple records or nested structures, this feature saves you from boilerplate code and improves code readability.
