Рубрики
Без рубрики

Оператор Java instanceof

Узнайте больше об операторе instanceof в Java

Автор оригинала: baeldung.

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 static  void 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 static  boolean isOfType(Object input) {
    return input instanceof T; // won't compile
}

Однако можно протестировать что-то вроде List :

if (collection instanceof List) {
    // do something
}

7. Заключение

В этом уроке мы узнали об операторе instanceof и о том, как его использовать. Полные образцы кода доступны на GitHub .