from JEP:
The following kinds of declarations can introduce either a named variable (denoted by an identifier) or an unnamed variable (denoted by an underscore):
- A local variable declaration statement in a block (JLS §14.4.2),
- The resource specification of a try-with-resources statement (JLS §14.20.3),
- The header of a basic for loop (JLS §14.14.1),
- The header of an enhanced for loop (JLS §14.14.2),
- An exception parameter of a catch block (JLS §14.20), and
- A formal parameter of a lambda expression (JLS §15.27.1).
before opening an issue, we need to discuss and decide on the possible check updates or new checks due to the presence of unnamed pattern and variables in these constructs
I tried to cover all possible cases in this example.
import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
record Point(int x, int y) {};
class Test {
void testLocalVariables(){
int _ = 4; // violation, but a false positive
int x = 4; // violation (expected)
}
void testForLoops() {
Queue<Integer> q = new PriorityQueue<>();
q.add(1);
for (Integer a : q) { // violation (expected)
q.poll();
}
for (int i = 0, k = Integer.valueOf(1); i < 3; i++) { } // violation (expected)
for (Integer _ : q) { // violation, but a false positive
q.poll();
}
for (int i = 0, _ = Integer.valueOf(1); i < 3; i++) { } // violation, but a false positive
}
public void testLambdaParameter() {
List<String> list = List.of("a", "b", "c");
List<String> _ = list.stream().map(character -> "x").toList(); // ok, but a false negative 'character' is unused
List<String> _ = list.stream().map(_ -> "x").toList(); // ok (expected)
}
public void testTryWithResourceAndCatchParameters() {
try (AutoCloseable a = new Scanner(System.in)) { // ok, but a false negative 'a' is unused
} catch (Exception e) { // ok, but a false negative 'e' is unused
System.out.println("error");
}
try (AutoCloseable _ = new Scanner(System.in)) { // ok (expected)
} catch (Exception _) { // ok (expected)
System.out.println("error");
}
}
public void testPatternVariables(Object obj) {
if (obj instanceof Point(int x, int y)) { // ok, but a false negative 'x' and 'y' is unused
}
if (obj instanceof Point(int _, int _)) { // ok (expected) unnamed pattern variables
}
if (obj instanceof Point(_,_)){ // ok (expected) unnamed pattern
}
}
}
PS D:\CS\test> java -jar checkstyle-10.14.2-all.jar -c config.xml src/Test.java
Starting audit...
[ERROR] D:\CS\test\src\Test.java:10:9: Unused local variable '_'. [UnusedLocalVariable]
[ERROR] D:\CS\test\src\Test.java:11:9: Unused local variable 'x'. [UnusedLocalVariable]
[ERROR] D:\CS\test\src\Test.java:17:14: Unused local variable 'a'. [UnusedLocalVariable]
[ERROR] D:\CS\test\src\Test.java:20:14: Unused local variable 'k'. [UnusedLocalVariable]
[ERROR] D:\CS\test\src\Test.java:22:14: Unused local variable '_'. [UnusedLocalVariable]
[ERROR] D:\CS\test\src\Test.java:25:14: Unused local variable '_'. [UnusedLocalVariable]
[ERROR] D:\CS\test\src\Test.java:30:9: Unused local variable '_'. [UnusedLocalVariable]
Audit done.
Checkstyle ends with 7 errors.
PS D:\CS\test>
from JEP:
The following kinds of declarations can introduce either a named variable (denoted by an identifier) or an unnamed variable (denoted by an underscore):
before opening an issue, we need to discuss and decide on the possible check updates or new checks due to the presence of unnamed pattern and variables in these constructs
I tried to cover all possible cases in this example.