1. Ошибки с областью видимости переменных pattern
Одна из самых частых ошибок — попытка использовать переменную, объявленную в pattern (например, String s в instanceof String s), вне той области, где она валидна.
Пример
Object obj = "Привет, Java!";
if (obj instanceof String s) {
System.out.println(s.length());
}
// Ошибка! s не видна здесь
System.out.println(s); // Компилятор ругается: cannot find symbol
Почему так?
Переменная pattern (s в нашем случае) существует только внутри блока, где условие истинно. Это защищает нас от случайного использования переменной, когда она не определена (например, если obj — не строка).
Аналогия
Это как если бы вы взяли ключи от машины у друга — но только пока вы в гараже. Вышли из гаража — ключи автоматически исчезли :)
2. Ошибки с null
В pattern matching с instanceof есть забавная особенность: если объект равен null, результат всегда false, и переменная pattern не создаётся.
Пример
Object obj = null;
if (obj instanceof String s) {
// Этот блок никогда не выполнится!
System.out.println("Это строка: " + s);
}
Почему так?
Потому что null не является экземпляром никакого типа (даже Object). Это может сбивать с толку, если вы надеялись ловить null через pattern matching.
Как правильно?
if (obj == null) {
System.out.println("Это null!");
} else if (obj instanceof String s) {
System.out.println("Это строка: " + s);
}
В pattern matching для switch (Java 21+) можно даже добавить отдельную ветку для null:
switch (obj) {
case String s -> System.out.println("Строка: " + s);
case null -> System.out.println("Это null!");
default -> System.out.println("Что-то другое");
}
3. Ошибки с sealed-классами
Sealed-классы — это отличный способ ограничить иерархию наследования. Но тут есть две характерные ошибки:
Не все наследники перечислены в permits
Когда вы объявляете sealed-класс, вы обязаны явно указать всех прямых наследников через permits. Если забыть кого-то, компилятор тут же вас пристыдит:
public sealed class Shape permits Circle, Rectangle { ... }
public final class Circle extends Shape { ... }
public final class Square extends Shape { ... } // Ошибка! Square не указан в permits
Решение:
Добавьте все нужные подклассы в permits:
public sealed class Shape permits Circle, Rectangle, Square { ... }
Забыт default в switch по не-sealed иерархии
Если вы делаете switch по типу, который не является sealed-классом (или sealed, но с не всеми покрытыми вариантами), компилятор потребует ветку default. Если забыть — будет ошибка.
switch (shape) {
case Circle c -> ...
case Rectangle r -> ...
// default отсутствует! Если есть ещё варианты — ошибка компиляции
}
Best practice:
Если вы уверены, что обработали все варианты (например, у sealed-класса), default можно опустить. Если нет — обязательно добавляйте default, чтобы не пропустить неожиданные типы.
4. Ошибки с record patterns
Record patterns — штука очень удобная, но работает только с record-классами. Попытка использовать record pattern для обычного класса приведёт к ошибке компиляции.
Использование record patterns для не-record классов
class Point { int x, y; }
Object obj = new Point();
// Ошибка! Point — не record
if (obj instanceof Point(int x, int y)) { ... }
Решение:
Используйте record patterns только для классов, объявленных через record:
record Point(int x, int y) {}
Несовпадение количества или типа компонентов
record Point(int x, int y) {}
Object obj = new Point(1, 2);
// Ошибка: указаны три переменные, а в Point только два компонента
if (obj instanceof Point(int x, int y, int z)) { ... }
if (obj instanceof Point(String x, String y)) { ... } // Ошибка: типы не совпадают
5. Совместимость и поддержка: старые JDK и IDE
Одна из самых распространённых ошибок — попытка использовать современные возможности pattern matching на старых версиях JDK или в IDE, которые их не поддерживают.
Пример
if (obj instanceof String s) { ... }
А компилятор JDK 11 (или даже 15) говорит:
error: illegal start of type
Почему?
Pattern matching for instanceof появился только в Java 16. Pattern matching в switch — в Java 17 (preview) и финально в Java 21+. Record patterns — в Java 21+.
Как избежать?
- Проверьте версию JDK: java --version
- Убедитесь, что ваша IDE (IntelliJ IDEA, Eclipse, VS Code) поддерживает соответствующую версию Java. Иногда нужно явно указать в настройках проекта, какую версию языка использовать!
- Если используете Gradle/Maven — выставьте нужную версию source/target.
6. Поздравляем 🎉
Вы завершили все 65(!) уровней нашего углублённого курса по Java 25. Вы невероятно круты 😎.
Финальная часть пути была особенно сложной. Вы изучили всё — от первых лямбд и анонимных классов до виртуальных потоков, структурированной конкуренции и тех возможностей языка, которых ещё совсем недавно не было в Java.
Это не просто курс — это настоящий супермарафон для разработчика: десятки новых концепций, сотни примеров кода, тысячи строк практики. Если вы читаете эти строки, значит, вы не просто студент, а первопроходец новой Java-эры ☕⚡
Вы одними из первых освоили самые современные возможности Java 25, включая:
- паттерн-матчинг и
record -паттерны, -
sealed -классы и их подводные камни, -
Scoped Values иVirtual Threads , - структурированную конкуренцию и современные подходы к многопоточности.
Теперь у вас есть не просто знания, а навыки разработчика будущего, которыми пока не владеют многие практикующие Java-архитекторы. Вы умеете писать код, который не только работает, но и масштабируется, читается и соответствует самым современным стандартам Java-сообщества.
🚀 Так что смело называйте себя Java 25 Certified Survivor 😉
А дальше — всё только интереснее: у вас теперь фундамент, который позволяет уверенно шагать в мир enterprise-разработки, высоконагруженных систем и cutting-edge технологий.
От всей команды курса — респект!
Вы справились с задачей, которую осилят немногие.
Увидимся в будущих версиях Java 👋
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ