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

Класс.isInstance vs Class.IsAssignableFrom

Краткий и практический обзор занятий.isInstance и Class.IsAssignableFrom методы.

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

1. введение

В этом кратком руководстве мы рассмотрим разницу между классом .isInstance и Class.IsAssignableFrom . Мы узнаем, как использовать каждый метод и каковы различия между ними.

2. Настройка

Давайте настроим интерфейс и пару классов для использования во время изучения класса .isInstance и Class.IsAssignableFrom функциональность.

Во-первых, давайте определим интерфейс:

public interface Shape {
}

Далее, давайте определим класс, который реализует Shape :

public class Triangle implements Shape {
}

Теперь мы создадим класс, который расширяет Треугольник :

public class IsoscelesTriangle extends Triangle {
}

3. Класс.isInstance

Метод isInstance в классе /эквивалентен оператору instanceof . Метод isInstance был введен в Java 1.1, поскольку его можно использовать динамически. Этот метод вернет true , если аргумент не является null и может быть успешно приведен к ссылочному типу без вызова ClassCastException .

Давайте посмотрим, как мы можем использовать метод isInstance с интерфейсом и классами, которые мы определили:

@Test
public void whenUsingIsInstanceProperly_desiredResultsHappen() {
    Shape shape = new Triangle();
    Triangle triangle = new Triangle();
    IsoscelesTriangle isoscelesTriangle = new IsoscelesTriangle();
    Triangle isoscelesTriangle2 = new IsoscelesTriangle();
    Shape nonspecificShape = null;
        
    assertTrue(Shape.class.isInstance(shape));
    assertTrue(Shape.class.isInstance(triangle));
    assertTrue(Shape.class.isInstance(isoscelesTriangle));
    assertTrue(Shape.class.isInstance(isoscelesTriangle2));
    assertFalse(Shape.class.isInstance(nonspecificShape));
        
    assertTrue(Triangle.class.isInstance(shape));
    assertTrue(Triangle.class.isInstance(triangle));
    assertTrue(Triangle.class.isInstance(isoscelesTriangle));
    assertTrue(Triangle.class.isInstance(isoscelesTriangle2));
        
    assertFalse(IsoscelesTriangle.class.isInstance(shape));
    assertFalse(IsoscelesTriangle.class.isInstance(triangle));
    assertTrue(IsoscelesTriangle.class.isInstance(isoscelesTriangle));
    assertTrue(IsoscelesTriangle.class.isInstance(isoscelesTriangle2));
}

Как мы видим, правая сторона может быть эквивалентна или более специфична, чем левая сторона . Предоставление null методу isInstance возвращает false .

4. Класс.IsAssignableFrom

Метод Class.IsAssignableFrom вернет true , если Class в левой части оператора совпадает с суперклассом или суперинтерфейсом предоставленного параметра Class .

Давайте использовать наши классы с помощью метода IsAssignableFrom :

@Test
public void whenUsingIsAssignableFromProperly_desiredResultsHappen() {
    Shape shape = new Triangle();
    Triangle triangle = new Triangle();
    IsoscelesTriangle isoscelesTriangle = new IsoscelesTriangle();
    Triangle isoscelesTriangle2 = new IsoscelesTriangle();
        
    assertFalse(shape.getClass().isAssignableFrom(Shape.class));
    assertTrue(shape.getClass().isAssignableFrom(shape.getClass()));
    assertTrue(shape.getClass().isAssignableFrom(triangle.getClass()));
    assertTrue(shape.getClass().isAssignableFrom(isoscelesTriangle.getClass()));
    assertTrue(shape.getClass().isAssignableFrom(isoscelesTriangle2.getClass()));
        
    assertFalse(triangle.getClass().isAssignableFrom(Shape.class));
    assertTrue(triangle.getClass().isAssignableFrom(shape.getClass()));
    assertTrue(triangle.getClass().isAssignableFrom(triangle.getClass()));
    assertTrue(triangle.getClass().isAssignableFrom(isoscelesTriangle.getClass()));
    assertTrue(triangle.getClass().isAssignableFrom(isoscelesTriangle2.getClass()));
        
    assertFalse(isoscelesTriangle.getClass().isAssignableFrom(Shape.class));
    assertFalse(isoscelesTriangle.getClass().isAssignableFrom(shape.getClass()));
    assertFalse(isoscelesTriangle.getClass().isAssignableFrom(triangle.getClass()));
    assertTrue(isoscelesTriangle.getClass().isAssignableFrom(isoscelesTriangle.getClass()));
    assertTrue(isoscelesTriangle.getClass().isAssignableFrom(isoscelesTriangle2.getClass()));
        
    assertFalse(isoscelesTriangle2.getClass().isAssignableFrom(Shape.class));
    assertFalse(isoscelesTriangle2.getClass().isAssignableFrom(shape.getClass()));
    assertFalse(isoscelesTriangle2.getClass().isAssignableFrom(triangle.getClass()));
    assertTrue(isoscelesTriangle2.getClass().isAssignableFrom(isoscelesTriangle.getClass()));
    assertTrue(isoscelesTriangle2.getClass().isAssignableFrom(isoscelesTriangle2.getClass()));
}

Как и в примере isInstance , мы ясно видим, что правая сторона должна быть либо такой же, либо более конкретной, чем левая. Мы также видим, что мы никогда не сможем назначить наш Shape интерфейс.

5. Различия

Теперь, когда мы изложили несколько подробных примеров, давайте рассмотрим некоторые различия:

  1. Чтобы использовать isInstance , нам нужно знать, что один из классов находится во время компиляции.
  2. Только IsAssignableFrom может использоваться с примитивами. Следует отметить, что если мы используем примитивы, метод будет возвращать true только в том случае, если объект Class и параметр Class точно совпадают Class .
  3. Метод IsAssignableFrom вызовет исключение |/NullPointerException , если объект, используемый по обе стороны выражения, является null . Если вы предоставите null методу isInstance , он вернет false . Мы должны думать о
  4. isInstance как об ответе на вопрос о том, является ли предоставленный объект типом, с которым мы его сравниваем (напрямую или через интерфейс или наследование). Мы можем думать о IsAssignableFrom как об ответе на вопрос о том, можем ли мы определить класс параметров как класс объектов. Другими словами, воля Треугольник Равнобедренный треугольник() компиляция?

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

В этом коротком уроке мы рассмотрели оба класса .isInstance и Class.IsAssignableFrom методы и изучил их использование и то, как они отличаются.

Как всегда, пример кода для этого урока можно найти на GitHub .