Istanza Java dell'operatore

1. Introduzione

In questo breve tutorial, impareremo a conoscere l' operatore instanceof in Java.

2. Qual è l' istanza dell'operatore?

instanceof è un operatore binario utilizzato per verificare se un oggetto è di un determinato tipo. Il risultato dell'operazione è vero o falso . È anche noto come operatore di confronto del tipo perché confronta l'istanza con il tipo.

Prima di lanciare un oggetto sconosciuto, è sempre necessario utilizzare l' istanza di controllo. In questo modo è possibile evitare ClassCastException in fase di esecuzione.

La sintassi di base dell'operatore instanceof è:

(object) instanceof (type)

Vediamo un esempio di base per l' operatore instanceof . Per prima cosa, creiamo un round di classe :

public class Round { // implementation details }

Successivamente, creiamo un anello di classe che si estende Round :

public class Ring extends Round { // implementation details }

Possiamo usare instanceof per verificare se un'istanza di Ring è di tipo Round :

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

3. Come funziona l' istanza dell'operatore?

L' operatore instanceof funziona sul principio della relazione is-a . Il concetto di relazione è-un si basa sull'ereditarietà della classe o sull'implementazione dell'interfaccia.

Per dimostrarlo, creiamo un'interfaccia Shape :

public interface Shape { // implementation details }

Creiamo anche una classe Circle che implementa l' interfaccia Shape ed estende anche la classe Round :

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

L' istanza del risultato sarà vera se l'oggetto è un'istanza del tipo:

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

Sarà anche vero se l'oggetto è un'istanza di una sottoclasse del tipo:

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

Se il tipo è un'interfaccia, restituirà true se l'oggetto implementa l'interfaccia:

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

L' operatore instanceof non può essere utilizzato se non esiste alcuna relazione tra l'oggetto che viene confrontato e il tipo con cui viene confrontato.

Creiamo una nuova classe Triangle che implementa Shape ma non ha alcuna relazione con Circle :

public class Triangle implements Shape { // implementation details }

Ora, se usiamo instanceof per verificare se un cerchio è un'istanza di triangolo :

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

Otterremo un errore di compilazione perché non esiste alcuna relazione tra le classi Circle e Triangle :

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

4. Utilizzo di instanceof con il tipo di oggetto

In Java, ogni classe eredita implicitamente dalla classe Object . Pertanto, l'utilizzo dell'operatore instanceof con il tipo Object restituirà sempre true :

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

5. Utilizzo dell'operatore instanceof quando un oggetto è nullo

Se utilizziamo l' operatore instanceof su qualsiasi oggetto null , restituisce false . Inoltre, non è necessario alcun controllo null quando si utilizza un operatore instanceof .

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

6. instanceof e Generics

I test e i cast delle istanze dipendono dall'ispezione delle informazioni sul tipo in fase di esecuzione. Pertanto, non possiamo usare instanceof insieme a tipi generici cancellati .

Ad esempio, se proviamo a compilare il seguente frammento:

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

Quindi otteniamo questo errore di compilazione:

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

Tecnicamente parlando, ci è permesso usare solo instanceof insieme a reifiedtipi in Java. Un tipo viene reificato se le relative informazioni sul tipo sono presenti in fase di esecuzione.

I tipi reificati in Java sono i seguenti:

  • Tipi primitivi come int
  • Classi e interfacce non generiche come String o Random
  • Tipi generici in cui tutti i tipi sono caratteri jolly illimitati come Set o Map
  • Tipi grezzi come List o HashMap
  • Matrici di altri tipi modificabili come String [], List [] o Map []

Poiché i parametri di tipo generico non sono reificati, non possiamo usarli neanche:

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

Tuttavia, è possibile testare qualcosa come List :

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

7. Conclusione

In questo tutorial, abbiamo imparato a conoscere l' operatore instanceof e come usarlo. Gli esempi di codice completi sono disponibili su GitHub.