Ответ
Pattern matching — это механизм, позволяющий проверять структуру объекта и извлекать из него значения в одном выражении. В Java он постепенно внедряется через несколько версий.
Основные формы pattern matching в Java:
1. Pattern matching для instanceof (Java 16+)
// Старый подход (до Java 16)
if (obj instanceof String) {
String s = (String) obj;
System.out.println(s.length());
}
// Новый подход с pattern matching
if (obj instanceof String s) {
// Переменная 's' автоматически приводится к String
System.out.println(s.length());
}
// Можно использовать в условиях
if (obj instanceof String s && s.length() > 5) {
System.out.println("Длинная строка: " + s);
}
2. Pattern matching в switch (Java 21+, preview в Java 17-20)
// Типизированный pattern matching в switch
String format(Object obj) {
return switch (obj) {
case Integer i -> String.format("int: %d", i);
case Long l -> String.format("long: %d", l);
case Double d -> String.format("double: %f", d);
case String s -> String.format("String: %s", s);
case null -> "null";
default -> obj.toString();
};
}
// С guard-условиями (when)
String checkNumber(Number n) {
return switch (n) {
case Integer i when i > 0 -> "Положительное целое";
case Integer i when i == 0 -> "Ноль";
case Integer i -> "Отрицательное целое";
case Double d when d > 0 -> "Положительное дробное";
default -> "Другое число";
};
}
3. Record patterns (Java 21+, preview)
record Point(int x, int y) {}
// Деструктуризация record в pattern matching
void printPoint(Object obj) {
if (obj instanceof Point(int x, int y)) {
System.out.printf("Точка: x=%d, y=%d%n", x, y);
}
}
// Вложенные record patterns
record Rectangle(Point topLeft, Point bottomRight) {}
double area(Object obj) {
return switch (obj) {
case Rectangle(Point(var x1, var y1), Point(var x2, var y2)) ->
Math.abs((x2 - x1) * (y2 - y1));
default -> 0.0;
};
}
Преимущества pattern matching:
- Упрощение кода — меньше boilerplate-кода для проверок и приведений типов
- Безопасность — исключаются ошибки приведения типов
- Выразительность — код лучше отражает намерения разработчика
- Поддержка null — явная обработка
nullв switch
Ограничения и особенности:
- Pattern matching для
instanceofдоступен с Java 16 (final) - Pattern matching в switch — с Java 21 (final), был в preview с Java 17
- Record patterns — с Java 21 (preview)
- Переменные в pattern matching имеют ограниченную область видимости (scope)
Практическое применение:
- Обработка разнотипных данных (парсинг, сериализация)
- Реализация посетителей (visitor pattern) без наследования
- Обработка AST (abstract syntax trees) в компиляторах и анализаторах
Ответ 18+ 🔞
Да ты посмотри, что эти умники в Java придумали! Pattern matching, блядь. Ну, наконец-то, ёпта! Сидели-сидели, смотрели на Scala и Kotlin, и мозги, наконец, прочистило.
Раньше-то, сука, как было? Хочешь проверить, что объект — строка, и с ней поработать?
if (obj instanceof String) {
String s = (String) obj; // Вот этот кастинг, блядь! Рука отвалится писать!
System.out.println(s.length());
}
Сплошное издевательство над клавиатурой и здравым смыслом. А теперь, с шестнадцатой Java, можно просто:
if (obj instanceof String s) {
// И всё, блядь! Переменная 's' уже тут, готовая, приведённая. Красота!
System.out.println(s.length());
}
Чувствуешь разницу? Как будто тебе с горы спустились, а не в гору карабкаться. И сразу в условии можно её использовать, хитрая жопа!
if (obj instanceof String s && s.length() > 5) {
System.out.println("Длинная строка: " + s);
}
А это, блядь, просто песня! Всё в одну строчку, чисто, ясно. Никакого лишнего мусора.
Но это, конечно, цветочки. Ягодки начались, когда в switch это запихнули (Java 21, окончательно, а то preview-версии — это отдельный пиздец, доверия ебать ноль).
Смотри, как красивше стало:
String format(Object obj) {
return switch (obj) {
case Integer i -> String.format("int: %d", i);
case Long l -> String.format("long: %d", l);
case Double d -> String.format("double: %f", d);
case String s -> String.format("String: %s", s);
case null -> "null"; // А нуля теперь не боится, сука! Явно указал — и спи спокойно.
default -> obj.toString();
};
}
Раньше бы тут на if-ах мозг сломать можно было, а теперь — раз, и готово. И guard-условия (when) добавили, вообще огонь:
String checkNumber(Number n) {
return switch (n) {
case Integer i when i > 0 -> "Положительное целое";
case Integer i when i == 0 -> "Ноль";
case Integer i -> "Отрицательное целое"; // Сюда уже все остальные целые попадут
case Double d when d > 0 -> "Положительное дробное";
default -> "Другое число";
};
}
Ну и вершина, блядь, этого цирка — record patterns (в Java 21 пока preview, но уже близко). Это когда у тебя есть record:
record Point(int x, int y) {}
И ты его можешь, сука, разобрать на запчасти прямо в условии! В рот меня чих-пых!
void printPoint(Object obj) {
if (obj instanceof Point(int x, int y)) { // Смотри! Просто взял и вытащил x и y!
System.out.printf("Точка: x=%d, y=%d%n", x, y);
}
}
А если record вложенный? Да похуй!
record Rectangle(Point topLeft, Point bottomRight) {}
double area(Object obj) {
return switch (obj) {
case Rectangle(Point(var x1, var y1), Point(var x2, var y2)) ->
Math.abs((x2 - x1) * (y2 - y1)); // И тут, блядь, всё разобрал! Красота-то какая!
default -> 0.0;
};
}
В чём, собственно, соль, а?
- Код короче. Меньше этой boilerplate-хуйни с кастами и проверками. Глаза не болят.
- Надёжнее. Шанс накосячить с приведением типа — ноль ебать. Компилятор сам всё проверит.
- Понятнее. Смотришь на код и сразу видишь, что происходит, а не разгадываешь китайскую грамоту из
if-ов. nullне страшен. Вswitchего теперь явно ловить можно, а не гадать, вылетит NPE или нет.
Но и подводные камни есть, куда без них:
instanceofс паттернами — с 16-й Java, всё стабильно.switchс паттернами — только с 21-й окончательно. До этого были preview-версии — играть в угадайку, что завтра сломают.- Record patterns — пока ещё в preview, так что терпения ебать нужно.
- Область видимости у переменных из паттерна — хитрая. Не везде её можно использовать, компилятор следит.
Где это всё, блядь, пригодится?
- Разбираешь какую-нибудь хуйню — JSON, XML, данные из сети. Всякие объекты разных типов приходят — вот тут pattern matching царь и бог.
- Писал бы Visitor pattern раньше? Теперь можно часто без этого овердохуища наследования обойтись.
- Компиляторы, анализаторы кода, AST (Abstract Syntax Tree) — тут вообще родная стихия для паттернов.
Короче, вещь нужная. Не то чтобы прям революция, но жить определённо стало проще. Как будто тяжёлую сумку с балкона сбросил.