
Java 21 introduced Unnamed Variables (_
) and Unnamed Patterns, making code cleaner and more readable by ignoring unused values. These features improve pattern matching, lambda expressions, and destructuring assignments.
1. What Are Unnamed Variables (_
)?
✅ Unnamed Variables (_
) are placeholders for values you don’t need.
✅ They improve readability by making it clear that a value is unused.
✅ They work in enhanced for
loops, try-with-resources, and lambda expressions.
2. Before Java 21: Ignoring Unused Variables (Messy Code)
🔴 Before Java 21, unused values had to be named even if they weren’t needed.
📌 Example: Before Java 21 (Naming Unused Variables)
record User(String name, int age) { }
public class Main {
public static void main(String[] args) {
User user = new User("Alice", 25);
// ❌ 'age' is not used, but we must name it
String name = user.name();
int age = user.age(); // Unused variable
}
}
✔ You still had to declare age
even though it’s not used.
3. Java 21+ Solution: Using _
to Ignore Unused Variables
🟢 Now you can use _
instead of declaring a variable you don’t need!
📌 Example: Using _
to Ignore Unused Variables
record User(String name, int age) { }
public class Main {
public static void main(String[] args) {
User user = new User("Alice", 25);
// ✅ Only extract 'name', ignore 'age'
String name = user.name();
int _ = user.age(); // Unused value (No warning, No error)
}
}
✔ No warnings for unused variables!
✔ Cleaner and more readable.
4. Unnamed Patterns in switch
and record
Matching
🚀 Unnamed Patterns allow _
in pattern matching and record
destructuring.
📌 Example: Ignoring Unused Fields in record
Matching
record User(String name, int age) { }
public class Main {
public static void main(String[] args) {
User user = new User("Alice", 25);
if (user instanceof User(String name, _)) { // ✅ Ignore 'age'
System.out.println("User: " + name);
}
}
}
✅ Output:
User: Alice
✔ You don’t need to name the age
field if it’s not used!
5. Using _
in Enhanced for
Loops
📌 Example: Ignoring Index in Loops (Before vs. After Java 21)
🔴 Before Java 21 (Unused Loop Variables Needed)
for (int i = 0; i < 10; i++) {
System.out.println("Hello!");
}
🟢 Java 21+ (Ignore i
with _
)
for (int _ = 0; _ < 10; _++) {
System.out.println("Hello!");
}
✔ The loop still runs, but _
makes it clear that i
is not used.
6. Using _
in Try-with-Resources
📌 Example: Ignoring a Resource in try-with-resources
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
try (BufferedReader _ = new BufferedReader(new FileReader("data.txt"))) {
System.out.println("Reading file...");
}
}
}
✔ The resource is still opened and closed properly, but _
indicates that it is not directly used.
7. Using _
in Lambda Expressions
📌 Example: Ignoring Unused Lambda Parameters
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> names = List.of("Alice", "Bob", "Charlie");
names.forEach((_ -> System.out.println("Processing...")));
}
}
✅ Output:
Processing...
Processing...
Processing...
✔ No need to name the variable if it’s unused in the lambda.
8. When Should You Use _
?
🚀 Use _
when:
✔ You have unused method parameters in lambdas.
✔ You are ignoring values in record
destructuring.
✔ You want cleaner loops or try-with-resources.
🚨 Do NOT use _
if:
❌ You actually need to use the variable.
❌ You are using Java 20 or earlier (This feature is Java 21+ only).
9. Comparison: Before Java 21 vs. Java 21+ (_
)
Feature | Before Java 21 | Java 21+ (_ ) |
---|---|---|
Ignoring Unused Variables | ❌ Had to name them | ✅ _ makes it clear |
Record Pattern Matching | ❌ Had to extract all fields | ✅ Use _ for unused fields |
Lambda Expressions | ❌ Named variables even if unused | ✅ _ for ignored parameters |
Lesson Reflection
- How does
_
improve code readability and reduce warnings for unused variables? - Why is
_
useful inrecord
pattern matching? - Can you think of a real-world scenario where ignoring values with
_
is helpful?
Answers to Reflection Questions on Unnamed Variables & Patterns (_
) – Java 21+
1️⃣ How does _
improve code readability and reduce warnings for unused variables?
✅ Before Java 21, you had to declare variables even if they were unused.
✅ Using _
makes it clear that a value is intentionally ignored, improving readability.
✅ Avoids compiler warnings about unused variables.
📌 Example: Before Java 21 (Unused Variable Warning)
record User(String name, int age) { }
public class Main {
public static void main(String[] args) {
User user = new User("Alice", 25);
String name = user.name();
int age = user.age(); // ❌ Unused variable warning
}
}
🚨 Problem: The compiler warns about age
being unused.
🟢 Java 21+ Solution: Use _
to Ignore Unused Values
record User(String name, int age) { }
public class Main {
public static void main(String[] args) {
User user = new User("Alice", 25);
String name = user.name();
int _ = user.age(); // ✅ No warning, `_` means we intentionally ignore it
}
}
✔ No more warnings, and the code is more readable!
2️⃣ Why is _
useful in record
pattern matching?
✅ Before Java 21, you had to extract all fields in record
pattern matching.
✅ With _
, you can ignore fields you don’t need.
📌 Example: Using _
in Record Pattern Matching
record User(String name, int age) { }
public class Main {
public static void main(String[] args) {
User user = new User("Alice", 25);
if (user instanceof User(String name, _)) { // ✅ Ignore 'age'
System.out.println("User: " + name);
}
}
}
✅ Output:
User: Alice
✔ Makes it clear that age
is intentionally ignored.
3️⃣ Can you think of a real-world scenario where ignoring values with _
is helpful?
🚀 Scenario 1: Ignoring Index in Loops
✔ In some cases, you need to iterate without using the loop index.
✔ _
makes it clear that the index is unused.
📌 Example: Ignoring Loop Index
for (int _ = 0; _ < 5; _++) {
System.out.println("Running task...");
}
✅ Output:
Running task...
Running task...
Running task...
Running task...
Running task...
✔ No unnecessary variable names cluttering the loop!
🚀 Scenario 2: Ignoring Unused Lambda Parameters
✔ Some APIs require lambda parameters that aren’t needed.
✔ _
makes it clear that a parameter is ignored.
📌 Example: Ignoring Lambda Parameters in forEach()
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> names = List.of("Alice", "Bob", "Charlie");
names.forEach((_ -> System.out.println("Processing...")));
}
}
✅ Output:
Processing...
Processing...
Processing...
✔ No need to name the variable if it’s unused!
🚀 Scenario 3: Ignoring Fields in JSON Processing
✔ Imagine you are parsing a JSON API response but only need specific fields.
📌 Example: Ignoring Unneeded JSON Fields
record ApiResponse(String status, int code, String message, String data) { }
public class Main {
public static void main(String[] args) {
ApiResponse response = new ApiResponse("OK", 200, "Success", "{...}");
if (response instanceof ApiResponse(_, _, String message, _)) {
System.out.println("API Message: " + message);
}
}
}
✅ Output:
API Message: Success
✔ Only extracts message
, ignoring other fields.
🔍 Key Takeaways
✔ Using _
makes it clear when a value is intentionally ignored.
✔ Prevents compiler warnings about unused variables.
✔ Works great in loops, lambdas, record
matching, and JSON processing.
The next Java 21+ feature: Sequenced Collections (List.of()
, Map.of()
order guarantee) 😊🚀