Pattern matching
Pattern matching — возможность проверить тип и сразу получить переменную этого типа без лишнего кастинга. Появился в Java 16 (instanceof), расширен в Java 21 (switch).
До Java 16 — проверка и каст вручную:
if (obj instanceof String) {
String s = (String) obj; // кастим отдельно — дублирование
System.out.println(s.length());
}
Java 16+ — pattern matching для instanceof:
if (obj instanceof String s) { // проверяет И сразу объявляет переменную s
System.out.println(s.length());
}
Java 21 — pattern matching в switch:
Object obj = getValue();
String result = switch (obj) {
case Integer i -> "Число: " + i;
case String s -> "Строка длиной " + s.length();
case null -> "null";
default -> "Что-то другое";
};
Guarded patterns — условие прямо в case:
switch (shape) {
case Circle c when c.radius() > 100 -> "Большой круг";
case Circle c -> "Маленький круг";
case Rectangle r -> "Прямоугольник";
}
Копнуть глубже
Exhaustiveness (полнота) — главная сила в связке с sealed. Если переключаемся по sealed типу — компилятор требует покрыть все варианты. Забыли один case → ошибка компиляции, а не NPE в рантайме:
sealed interface Notification permits Email, Push, SMS {}
// Компилятор не даст скомпилировать если забыть один из трёх case
String format(Notification n) {
return switch (n) {
case Email e -> "Email: " + e.address();
case Push p -> "Push: " + p.deviceId();
case SMS s -> "SMS: " + s.phone();
};
}
Деконструкция record (Java 21). Pattern matching умеет «распаковывать» record прямо в switch:
record Point(int x, int y) {}
Object obj = new Point(3, 4);
if (obj instanceof Point(int x, int y)) { // деконструкция
System.out.println(x + ", " + y); // сразу x и y без геттеров
}
Порядок case важен. Более специфичные паттерны должны стоять выше общих — иначе компилятор ошибка «доминирование паттерна»:
switch (s) {
case Circle c when c.radius() > 0 -> ... // ✅ сначала частный случай
case Circle c -> ... // ✅ потом общий
}
// Наоборот — ошибка компиляции: второй case никогда не достигается
🎤 Закрыл тему, если можешь объяснить:
• как pattern matching для instanceof упрощает работу с типами;
• что такое guarded patterns и почему sealed + switch обеспечивают exhaustiveness (если дошёл до 2-го слоя).
• что такое guarded patterns и почему sealed + switch обеспечивают exhaustiveness (если дошёл до 2-го слоя).