Summary
Based on experiences with the previous preview of the record patterns feature, we propose a few improvements and simplifications.
Problem
Three issues related to record patterns have been identified:
Named record patterns (for example
R(String s) r
) introduce an ambiguity in the grammar, and their value appears to be low.Allowing a record pattern in an enhanced
for
statement would make it easy to loop over a collection of record values and swiftly extract the components of each record.Record patterns for generic record classes currently require type arguments to be given explicitly. But in most circumstances reasonable type arguments could be inferred automatically.
Solution
Named Record Patterns
We propose to drop the named record patterns feature.
Record Patterns in Enhanced For
We propose to permit record patterns to appear in the header of an enhanced
for
statement. For example:
record Complex(double real, double img) {}
List<Complex> list = ...;
for (Complex(var real, var img) : list) {
// can use "real" and "img" directly
}
Currently, the grammar for the enhanced for
statement requires the header to
contain a LocalVariableDeclaration
. We propose to extend this and also support
a record pattern.
Any pattern variables introduced by the record pattern are in scope in the body
of the enhanced for
statement.
It is required that a record pattern appearing in the header is exhaustive for the type of the elements being iterating over.
At runtime, if an iteration element is null
, and a record pattern appears in
the header, then the enhanced for
statement raises a MatchException
that wraps NullPointerException
.
Record Pattern Type Inference
Previously, record patterns for generic record classes required type arguments to be given explicitly, and the use of a raw type in this case was forbidden. It is proposed in this preview that using a raw type will be allowed and will now entail that inference of the type arguments is performed using the type information from the expression being pattern matched.
record Pair<S,T>(S x, T y) { };
Pair<Integer, String> p = ...;
if (p instanceof Pair(var x, var y)) {
// inferred to be Pair<Integer, String>(var x, var y)
...
}
If a type can not be inferred then a compile-time error occurs.
Specification
The specification draft is available for convenience here: http://cr.openjdk.java.net/~gbierman/jep432%2b433/jep432%2b433-20221028/specs/patterns-switch-record-patterns-jls.html and is attached as jls-jep432+433-20221028.zip. Please note that, for technical reasons, the specification draft also includes changes for JEP-433 (https://openjdk.org/jeps/433), which are reviewed under CSR JDK-8294946.
The specdiff for API changes is available for convenience here: http://cr.openjdk.java.net/~jlahoda/8294945/specdiff.00/overview-summary.html, and is attached as specdiff.00.zip.
- csr of
-
JDK-8294942 Compiler implementation for Record Patterns (Second Preview)
-
- Resolved
-
- relates to
-
JDK-8304401 Compiler Implementation for Record Patterns
-
- Closed
-