CodeGym /Java Blog /Random-IT /Operatore istanza di Java
John Squirrels
Livello 41
San Francisco

Operatore istanza di Java

Pubblicato nel gruppo Random-IT
CIAO! Oggi parleremo dell'operatore instanceof , considereremo esempi di come viene utilizzato e toccheremo alcuni aspetti di come funziona :) Hai già incontrato questo operatore nei primi livelli di CodeGym. Ti ricordi perché ne abbiamo bisogno? In caso contrario, non preoccuparti. Ricordiamo insieme. L' operatore instanceof è necessario per verificare se un oggetto a cui fa riferimento una variabile X è stato creato sulla base di una classe Y. Sembra semplice. Perché siamo tornati su questo argomento? Prima di tutto, perché ora conosci bene il meccanismo di ereditarietà di Java e gli altri principi dell'OOP. L' operatore instanceof sarà ora molto più chiaro e vedremo esempi più avanzati di come viene utilizzato. Andiamo!Come funziona l'operatore instanceof - 1Probabilmente ricorderai che l' operatore instanceof restituisce true se il controllo restituisce true o false se l'espressione è false. Di conseguenza, di solito ricorre in tutti i tipi di espressioni condizionali ( if…else ). Iniziamo con alcuni esempi più semplici:

public class Main {

   public static void main(String[] args) {

       Integer x = new Integer(22);

       System.out.println(x instanceof Integer);
   }
}
Cosa pensi verrà visualizzato sulla console? Bene, qui è ovvio.:) L' oggetto x è un numero intero, quindi il risultato sarà true . Output della console: True Proviamo a verificare se si tratta di una String :

public class Main {

   public static void main(String[] args) {

       Integer x = new Integer(22);

       System.out.println(x instanceof String); // Error!
   }
}
Abbiamo un errore. E attenzione: il compilatore ha generato l'errore prima di eseguire il codice! Ha immediatamente visto che Integer e String non possono essere convertiti automaticamente l'uno con l'altro e non sono correlati tramite ereditarietà. Di conseguenza, un oggetto Integer non viene creato in base a String . Questo è conveniente e aiuta a evitare strani errori di runtime, quindi il compilatore ci ha aiutato qui :) Ora proviamo a considerare esempi più difficili. Poiché abbiamo menzionato l'ereditarietà, lavoriamo con il seguente piccolo sistema di classi:

public class Animal {

}

public class Cat extends Animal {

}

public class MaineCoon extends Cat {

}
Sappiamo già come si comporta instanceof quando controlliamo se un oggetto è un'istanza di una classe, ma cosa succede se consideriamo la relazione genitore-figlio? Ad esempio, cosa pensi che produrranno queste espressioni:

public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();

       System.out.println(cat instanceof Animal);

       System.out.println(cat instanceof MaineCoon);

   }
}
Output: True False La domanda principale a cui occorre rispondere è esattamente come instanceof interpreta 'oggetto creato sulla base di una classe'? ' cat instanceof Animal ' restituisce true , ma sicuramente possiamo trovare difetti in questa formulazione. Perché un oggetto Cat viene creato in base alla classe Animal ? Non è stato creato basandosi solo sulla sua stessa classe? La risposta è abbastanza semplice e potresti averci già pensato. Ricorda l'ordine in cui i costruttori vengono chiamati e le variabili vengono inizializzate durante la creazione di un oggetto. Abbiamo già trattato questo argomento nell'articolo sui costruttori di classi . Ecco un esempio tratto da quella lezione:

public class Animal {

   String brain = "Initial value of brain in the Animal class";
   String heart = "Initial value of heart in the Animal class";

   public static int animalCount = 7700000;

   public Animal(String brain, String heart) {
       System.out.println("Animal base class constructor is running");
       System.out.println("Have the variables of the Animal class already been initialized?");
       System.out.println("Current value of static variable animalCount = " + animalCount);
       System.out.println("Current value of brain in the Animal class = " + this.brain);
       System.out.println("Current value of heart in the Animal class = " + this.heart);
       System.out.println("Have the variables of the Cat class already been initialized?");
       System.out.println("Current value of static variable catCount = " + Cat.catCount);

       this.brain = brain;
       this.heart = heart;
       System.out.println("Animal base class constructor is done!");
       System.out.println("Current value of brain = " + this.brain);
       System.out.println("Current value of heart = " + this.heart);
   }
}

public class Cat extends Animal {

   String tail = "Initial value of tail in the Cat class";

   static int catCount = 37;

   public Cat(String brain, String heart, String tail) {
       super(brain, heart);
       System.out.println("The Cat class constructor has started (The Animal constructor already finished)");
       System.out.println("Current value of static variable catCount = " + catCount);
       System.out.println("Current value of tail = " + this.tail);
       this.tail = tail;
       System.out.println("Current value of tail = " + this.tail);
   }

   public static void main(String[] args) {
       Cat cat = new Cat("Brain", "Heart", "Tail");
   }
}
E se lo esegui nell'IDE, l'output della console sarà simile a questo: Il costruttore della classe base Animal è in esecuzione Le variabili della classe Animal sono già state inizializzate? Valore attuale della variabile statica animalCount = 7700000 Valore attuale del cervello nella classe Animale = Valore iniziale del cervello nella classe Animale Valore attuale del cuore nella classe Animale = Valore iniziale del cuore nella classe Animale Sono già presenti le variabili della classe Gatto stato inizializzato? Valore corrente della variabile statica catCount = 37 Il costruttore della classe base animale è terminato! Valore corrente di brain = Brain Valore corrente heart = Heart Il costruttore della classe cat è iniziato (il costruttore Animal è già terminato) Valore corrente della variabile statica catCount = 37 Valore corrente di tail = Valore iniziale di tail nella classe Cat Valore corrente di tail = Coda Adesso ti ricordi?:) Il costruttore della classe base, se c'è una classe base, viene sempre chiamato per primo quando si crea un oggetto. L' operatore instanceof è guidato da questo principio quando cerca di determinare se un oggetto A è stato creato sulla base di una classe B. Se viene chiamato il costruttore della classe base, non ci possono essere dubbi. Con il secondo controllo, tutto è più semplice:

System.out.println(cat instanceof MaineCoon);
Il costruttore MaineCoon non è stato chiamato quando è stato creato l'oggetto Cat , il che ha senso. Dopotutto, MaineCoon è un discendente di Cat , non un antenato. E non è un modello per Cat . Ok, penso che siamo chiari su questo. Ma cosa succede se lo facciamo?:

public class Main {

   public static void main(String[] args) {

       Cat cat = new MaineCoon();

       System.out.println(cat instanceof Cat);
       System.out.println(cat instanceof MaineCoon);


   }
}
Hmm... ora è più difficile. Parliamone. Abbiamo una variabile Cat a cui abbiamo assegnato un oggetto MaineCoon . A proposito, perché funziona? Possiamo farlo, giusto? Sì possiamo. Dopo tutto, ogni MaineCoon è un gatto. Se questo non è del tutto chiaro, ricorda l'esempio dell'ampliamento dei tipi primitivi:

public class Main {

   public static void main(String[] args) {

       long x = 1024;

   }
}
Il numero 1024 è un numero breve : si inserisce facilmente in una variabile lunga , poiché ci sono abbastanza byte per accoglierlo (ricordate l'esempio con le bambole?). Un oggetto discendente può sempre essere assegnato a una variabile antenata. Per ora, ricorda solo questo, e nelle lezioni successive analizzeremo come funziona. Quindi cosa produce il nostro esempio?

Cat cat = new MaineCoon();
System.out.println(cat instanceof Cat);
System.out.println(cat instanceof MaineCoon);
Cosa verificherà instanceof ? la nostra variabile Cat o il nostro oggetto MaineCoon ? La risposta è che questa domanda è in realtà semplice. Devi solo leggere di nuovo la definizione dell'operatore: l' operatore instanceof è necessario per verificare se un oggetto a cui fa riferimento una variabile X è stato creato sulla base di una classe Y. L' operatore instanceof verifica l'origine di un oggetto, non il tipo di variabile. Pertanto, in questo esempio, il nostro programma mostrerà true in entrambi i casi: abbiamo un oggetto MaineCoon . Ovviamente, è stato creato sulla base della classe MaineCoon , ma è stato creato sulla base del gattoanche la classe dei genitori!
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION