org.sonar.l10n.java.rules.java.S6878.html Maven / Gradle / Ivy
Why is this an issue?
Java 21 enhances Pattern Matching, introduced in Java 16, with a record pattern that decomposes records into local variables. This form
should be used when all fields of a record are accessed within a block for improved readability. Nested record patterns are also allowed and should be
used when a record field is another record, and all its fields are accessed.
Exceptions
This rule does not apply when not all record fields are accessed. This prevents the creation of unused local variables in the decomposed record
structure.
How to fix it
Replace the instance check or simple pattern matching with a record pattern.
Code examples
Noncompliant code example
This example uses pattern matching but not a record pattern, even though all fields of the record are accessed in the block.
record Point(Float x, Float y, Float z) {}
void print(Object obj) {
if (obj instanceof Point p) { // Noncompliant, because all three fields x, y, z are accessed
Float x = p.x;
Float y = p.y();
System.out.println(x + y + p.z);
}
}
Compliant solution
The compliant example uses a record pattern to decompose the record structure.
record Point(Float x, Float y, Float z) {}
void print(Object obj) {
if (obj instanceof Point(Float x, Float y, Float z)) { // Compliant
System.out.println(x + y + z);
}
}
Noncompliant code example
This example does not use pattern matching or a record pattern. Rule {rule:java:S6201} - Pattern matching or "instanceOf" operator should be
used would report first. When fixed using simple pattern matching instead of a record pattern, this rule ({rule:java:S6878}) will report.
void print(Object obj) {
if (obj instanceof Point) { // Noncompliant
Point p = (Point) obj;
Float x = p.x;
Float y = p.y();
System.out.println(x + y + p.z);
}
}
Compliant solution
The solution compliant with both rules, {rule:java:S6201} and {rule:java:S6878}, uses pattern matching and decomposes the record structure using a
record pattern.
void print(Object obj) {
if (obj instanceof Point(Float x, Float y, Float z)) { // Compliant
System.out.println(x + y + z);
}
}
Noncompliant code example
This example is noncompliant because a nested record pattern could have been used.
record Plane(Point normal, Float d) {}
void print(Object obj) {
// Noncompliant, because all field of "normal" are accessed
if (obj instanceof Plane(Point normal, Float d)) {
System.out.println(normal.x + normal.y + normal.z);
System.out.println(d);
}
}
Compliant solution
This is the same example using a nested record pattern.
void print(Object obj) {
if (obj instanceof Plane(Point(Float x, Float y, Float z), Float d)) { // Compliant
System.out.println(x + y + z);
System.out.println(d);
}
}
Compliant solution
This example uses var
instead of replicating the field types in the record pattern, which is less verbose and keeps the code more
readable, especially in the case of longer type names. Also, it uses variable names that do not match the original field names. The reason for this
can be to avoid name collisions with fields or other local variables.
void print(Object obj) {
if (obj instanceof Point(var px, var py, var pz)) { // Compliant
System.out.println(px + py + pz);
}
}
Compliant solution
This example is compliant without using a record pattern, as it does not access all fields.
void print(Object obj) {
if (obj instanceof Point p) { // Compliant, because z is never accessed
Float x = p.x;
Float y = p.y();
System.out.println(x + y);
}
}
Resources