История вопроса
Оператор instanceof был введён в Java для возможности проверки, принадлежит ли объект определённому типу (классу или интерфейсу) перед приведением типов. Это стало актуально для работы с наследованием, полиморфизмом и обработкой неоднородных коллекций объектов.
Проблема
Без проверки принадлежности к типу можно получить ClassCastException при приведении типов. Неправильное использование instanceof может ухудшить архитектуру кода, привести к анти-паттернам (например, частому применению вместо полиморфизма).
Решение
Оператор instanceof возвращает true, если объект не null и относится к проверяемому типу или реализует указанный интерфейс.
Пример кода:
Object obj = "Hello"; if (obj instanceof String) { String str = (String) obj; System.out.println(str.toUpperCase()); }
Ключевые особенности:
Что вернёт obj instanceof SomeClass если obj == null?
instanceof всегда возвращает false, если объект null, независимо от проверяемого типа. Это важно для предотвращения NullPointerException.
Можно ли использовать instanceof для проверки принадлежности к интерфейсу?
Да. instanceof используется для проверки, реализует ли объект нужный интерфейс, а не только принадлежность к определённому классу.
Пример кода:
Runnable r = () -> {}; System.out.println(r instanceof Runnable); // true
Что будет, если класс компилируется с --release 16+ и паттерн-матчинг для instanceof уже внедрён?
С Java 16+ оператор instanceof поддерживает pattern matching, то есть можно сразу в проверке указать переменную и избежать явного кастинга.
Пример кода:
Object obj = "Test string"; if (obj instanceof String str) { System.out.println(str.length()); }
В большом проекте логику бизнес-обработки строили на серию if (obj instanceof X)..., а не через переопределение методов. Это усложнило сопровождение: появление нового типа требовало менять все проверки.
Плюсы:
Минусы:
В схожем проекте для расширяемой иерархии использовали абстрактные методы, а instanceof только для проверки особых edge-кейсов.
Плюсы:
Минусы: