1. введение
В этом кратком руководстве мы узнаем об операторе instanceof в Java.
2. Что такое оператор instanceof?
instanceof-это двоичный оператор, используемый для проверки того, является ли объект заданным типом. Результатом операции является либо true , либо false . Он также известен как оператор сравнения типов, потому что он сравнивает экземпляр с типом.
Перед приведением неизвестного объекта всегда следует использовать проверку instanceof . Это помогает избежать ClassCastException во время выполнения.
Базовый синтаксис оператора instanceof :
(object) instanceof (type)
Давайте рассмотрим базовый пример для оператора instanceof . Во-первых, давайте создадим класс Round :
public class Round { // implementation details }
Далее, давайте создадим класс Ring , который расширяется Вокруг :
public class Ring extends Round { // implementation details }
Мы можем использовать instanceof , чтобы проверить, имеет ли экземпляр Ring тип Round :
@Test public void givenWhenInstanceIsCorrect_thenReturnTrue() { Ring ring = new Ring(); Assert.assertTrue(ring instanceof Round); }
3. Как работает оператор instanceof?
Оператор instanceof работает по принципу отношения is-a . Концепция отношения is-a основана на реализации класса наследования или интерфейса.
Чтобы продемонстрировать это, давайте создадим интерфейс Shape :
public interface Shape { // implementation details }
Давайте также создадим класс Circle , который реализует интерфейс Shape , а также расширяет класс Round :
public class Circle extends Round implements Shape { // implementation details }
То instanceof результат будет истинный если объект является экземпляром типа:
@Test public void givenWhenObjectIsInstanceOfType_thenReturnTrue() { Circle circle = new Circle(); Assert.assertTrue(circle instanceof Circle); }
Это тоже будет истинный если объект является экземпляром подкласса типа:
@Test public void giveWhenInstanceIsOfSubtype_thenReturnTrue() { Circle circle = new Circle(); Assert.assertTrue(circle instanceof Round); }
Если тип является интерфейсом, он вернет истинный если объект реализует интерфейс:
@Test public void givenWhenTypeIsInterface_thenReturnTrue() { Circle circle = new Circle(); Assert.assertTrue(circle instanceof Shape); }
Пример оператор не может быть использован, если нет связи между сравниваемым объектом и типом, с которым он сравнивается.
Давайте создадим новый класс Triangle , который реализует Shape , но не имеет никакого отношения к Circle :
public class Triangle implements Shape { // implementation details }
Теперь, если мы используем instanceof , чтобы проверить, является ли Circle экземпляром Треугольник :
@Test public void givenWhenComparingClassInDiffHierarchy_thenCompilationError() { Circle circle = new Circle(); Assert.assertFalse(circle instanceof Triangle); }
Мы получим ошибку компиляции, потому что нет никакой связи между классами Circle и Triangle :
java.lang.Error: Unresolved compilation problem: Incompatible conditional operand types Circle and Triangle
4. Использование instanceof с типом объекта
В Java каждый класс неявно наследуется от класса Object . Поэтому использование оператора instanceof с типом Object всегда будет иметь значение true :
@Test public void givenWhenTypeIsOfObjectType_thenReturnTrue() { Thread thread = new Thread(); Assert.assertTrue(thread instanceof Object); }
5. Использование оператора instanceof, Когда Объект Равен null
Если мы используем оператор instanceof для любого объекта , который является null , он возвращает false . Кроме того, при использовании оператора instanceof проверка null не требуется.
@Test public void givenWhenInstanceValueIsNull_thenReturnFalse() { Circle circle = null; Assert.assertFalse(circle instanceof Round); }
6. instanceof и дженерики
Тесты экземпляров и приведения зависят от проверки информации о типе во время выполнения. Поэтому мы не можем использовать instanceof вместе с стертыми универсальными типами .
Например, если мы попытаемся скомпилировать следующий фрагмент:
public staticvoid sort(List collection) { if (collection instanceof List ) { // sort strings differently } // omitted }
Затем мы получаем эту ошибку компиляции:
error: illegal generic type for instanceof if (collection instanceof List) { ^
Технически говоря, нам разрешено использовать только instanceof вместе с овеществленными | типами в Java. Тип овеществляется, если информация о его типе присутствует во время выполнения.
Овеществленные типы в Java следующие:
- Примитивные типы, такие как int
- Не Универсальные классы и интерфейсы, такие как String или Random
- Универсальные типы, в которых все типы являются неограниченными подстановочными знаками, такими как Set или Map ? > ? >
- Необработанные типы, такие как List или HashMap
- Массивы других reifiable типов, таких как String [], List [], или Map ?>[] ?>[]
Поскольку параметры универсального типа не овеществляются, мы также не можем их использовать:
public staticboolean isOfType(Object input) { return input instanceof T; // won't compile }
Однако можно протестировать что-то вроде List :
if (collection instanceof List>) { // do something }
7. Заключение
В этом уроке мы узнали об операторе instanceof и о том, как его использовать. Полные образцы кода доступны на GitHub .