Instancja operatora Java

1. Wstęp

Z tego krótkiego samouczka dowiemy się o operatorze instanceof w Javie.

2. Co to jest instancja Operatora?

instanceof jest operatorem binarnym używanym do testowania, czy obiekt jest danego typu. Wynik operacji to prawda lub fałsz . Jest również znany jako operator porównania typów, ponieważ porównuje wystąpienie z typem.

Przed rzuceniem nieznanego obiektu należy zawsze używać instancji check. Takie postępowanie pomaga uniknąć wyjątku ClassCastException w czasie wykonywania.

W instanceof Podstawowa składnia operatora jest:

(object) instanceof (type)

Zobaczmy podstawowy przykład operatora instanceof . Najpierw utwórzmy klasę Round :

public class Round { // implementation details }

Następnie stwórzmy klasę Ring, która rozszerza Round :

public class Ring extends Round { // implementation details }

Możemy użyć instanceof, aby sprawdzić, czy instancja Ring jest typu Round :

@Test public void givenWhenInstanceIsCorrect_thenReturnTrue() { Ring ring = new Ring(); Assert.assertTrue(ring instanceof Round); }

3. Jak działa instancja Operatora?

Instanceof operator działa na zasadzie IS-relacji . Pojęcie relacji jest-a jest oparte na dziedziczeniu klas lub implementacji interfejsu.

Aby to zademonstrować, utwórzmy interfejs Shape :

public interface Shape { // implementation details }

Utwórzmy również klasę Circle, która implementuje interfejs Shape , a także rozszerza klasę Round :

public class Circle extends Round implements Shape { // implementation details }

Wynik instanceof będzie prawdziwy, jeśli obiekt jest instancją typu:

@Test public void givenWhenObjectIsInstanceOfType_thenReturnTrue() { Circle circle = new Circle(); Assert.assertTrue(circle instanceof Circle); }

Będzie to również prawdziwe, jeśli obiekt jest instancją podklasy typu:

@Test public void giveWhenInstanceIsOfSubtype_thenReturnTrue() { Circle circle = new Circle(); Assert.assertTrue(circle instanceof Round); }

Jeśli typ jest interfejsem, zwróci wartość true, jeśli obiekt implementuje interfejs:

@Test public void givenWhenTypeIsInterface_thenReturnTrue() { Circle circle = new Circle(); Assert.assertTrue(circle instanceof Shape); }

Operatora instanceof nie można używać, jeśli nie ma związku między porównywanym obiektem a typem, z którym jest porównywany.

Stwórzmy nową klasę Triangle, która implementuje Shape, ale nie ma związku z Circle :

public class Triangle implements Shape { // implementation details }

Teraz, jeśli użyjemy instanceof do sprawdzenia, czy Circle jest instancją Triangle :

@Test public void givenWhenComparingClassInDiffHierarchy_thenCompilationError() { Circle circle = new Circle(); Assert.assertFalse(circle instanceof Triangle); }

Otrzymamy błąd kompilacji, ponieważ nie ma związku między klasami Circle i Triangle :

java.lang.Error: Unresolved compilation problem: Incompatible conditional operand types Circle and Triangle

4. Użycie instanceof z typem obiektu

W Javie każda klasa dziedziczy niejawnie po klasie Object . Dlatego użycie operatora instanceof z typem Object zawsze daje wartość true :

@Test public void givenWhenTypeIsOfObjectType_thenReturnTrue() { Thread thread = new Thread(); Assert.assertTrue(thread instanceof Object); }

5. Korzystanie z operatora instanceof, gdy obiekt jest pusty

Jeśli użyjemy operatora instanceof na dowolnym obiekcie o wartości null , zwróci on wartość false . W przypadku korzystania z operatora instanceof nie jest również wymagane sprawdzanie wartości null .

@Test public void givenWhenInstanceValueIsNull_thenReturnFalse() { Circle circle = null; Assert.assertFalse(circle instanceof Round); }

6. instanceof i Generics

Testy i rzuty instancji zależą od sprawdzania informacji o typie w czasie wykonywania. Dlatego nie możemy używać instanceof razem z wymazanymi typami ogólnymi .

Na przykład, jeśli spróbujemy skompilować następujący fragment:

public static  void sort(List collection) { if (collection instanceof List) { // sort strings differently } // omitted }

Następnie otrzymujemy ten błąd kompilacji:

error: illegal generic type for instanceof if (collection instanceof List) { ^

Z technicznego punktu widzenia możemy używać tylko instancji instancji razem z reifiedtypy w Javie. Typ jest reifikowany, jeśli jego informacje o typie są obecne w czasie wykonywania.

Typy reifikowane w Javie są następujące:

  • Typy prymitywne, takie jak int
  • Nieogólne klasy i interfejsy, takie jak String lub Random
  • Typy ogólne, w których wszystkie typy są nieograniczonymi symbolami wieloznacznymi, takimi jak Set lub Map
  • Surowe typy, takie jak List lub HashMap
  • Tablice innych typów wielokrotnego użytku, takich jak String [], List [] lub Map []

Ponieważ parametry typu ogólnego nie są reifikowane, nie możemy ich również użyć:

public static  boolean isOfType(Object input) { return input instanceof T; // won't compile }

Można jednak przetestować coś takiego jak List :

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

7. Wnioski

W tym samouczku nauczyliśmy się o operatorze instanceof i jak go używać. Pełne przykłady kodu są dostępne na GitHub.