L'operatore instanceof
Fa parte della sezione Programmazione orientata agli oggetti del percorso Java di Coddy. Lezione 31 di 87.
La lezione precedente ha mostrato che il downcasting può fallire con una ClassCastException se l'oggetto non è effettivamente del tipo a cui stai eseguendo il cast. L'operatore instanceof risolve questo problema consentendoti di verificare il tipo di un oggetto prima di eseguire il cast.
La sintassi è semplice: object instanceof ClassName restituisce true se l'oggetto è un'istanza di quella classe (o di una qualsiasi delle sue sottoclassi):
Animal animal = new Dog();
if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.bark(); // È sicuro chiamare i metodi specifici di Dog
}Questo controllo previene gli errori di runtime assicurandosi che il cast abbia esito positivo. L'operatore restituisce anche true per i tipi genitore nella gerarchia:
Dog dog = new Dog();
System.out.println(dog instanceof Dog); // true
System.out.println(dog instanceof Animal); // true
System.out.println(dog instanceof Object); // trueA partire da Java 16, puoi combinare il controllo e il cast in un unico passaggio usando il pattern matching:
if (animal instanceof Dog dog) {
dog.bark(); // 'dog' è già stato convertito nel tipo corretto ed è pronto per essere usato
}Questa sintassi più pulita elimina la riga di cast separata. Nota che instanceof restituisce false quando viene verificato con null, quindi non ti serve un controllo null separato.
Sfida
FacileCostruiamo un sistema di ispezione dei veicoli che usa l'operatore instanceof per identificare e gestire in modo sicuro diversi tipi di veicoli. Creerai una gerarchia di veicoli e scriverai codice che controlla il tipo effettivo di ciascun veicolo prima di accedere alle sue funzionalità specifiche.
Organizzerai il codice in quattro file:
Vehicle.java: Crea la classe base condivisa da tutti i veicoli. Ogni veicolo ha un campomodel(String). Includi un costruttore per inizializzarlo, un metodo gettergetModel()e un metodoinspect()che stampa:Inspecting vehicle: [model]Car.java: Crea una classe che estende Vehicle. Le auto hanno un campo aggiuntivonumDoors(int). Usasuperper l'inizializzazione della classe genitore. Aggiungi un metodocheckDoors()che stampa:[model] has [numDoors] doorsMotorcycle.java: Crea un'altra classe che estende Vehicle. Le motociclette hanno un campohasSidecar(boolean). Aggiungi un metodocheckSidecar()che stampa[model] has a sidecaroppure[model] has no sidecar, a seconda del valore booleano.Main.java: È qui cheinstanceofdiventa essenziale! Riceverai quattro input: un modello di auto, il numero di porte, un modello di motocicletta e se ha un sidecar (true/false).Crea un array di riferimenti
Vehiclecontenente un'auto e una motocicletta. Poi esegui un ciclo sull'array e, per ogni veicolo:- Chiama il metodo base
inspect() - Usa
instanceofper verificare se è un'auto; in tal caso, esegui il downcast in modo sicuro e chiamacheckDoors() - Usa
instanceofper verificare se è una motocicletta; in tal caso, esegui il downcast in modo sicuro e chiamacheckSidecar()
- Chiama il metodo base
Riceverai quattro input: il modello dell'auto (String), il numero di porte (int), il modello della motocicletta (String) e l'indicazione della presenza di un sidecar (boolean).
L'output deve mostrare quattro righe: per ogni veicolo, vedrai il messaggio di ispezione seguito dal controllo specifico del suo tipo. L'operatore instanceof garantisce che tu chiami i metodi di Car solo sulle auto effettive e i metodi di Motorcycle solo sulle motociclette effettive, evitando qualsiasi ClassCastException!
Provalo tu
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Leggi i dati di input
String carModel = scanner.nextLine();
int numDoors = Integer.parseInt(scanner.nextLine());
String motorcycleModel = scanner.nextLine();
boolean hasSidecar = Boolean.parseBoolean(scanner.nextLine());
// TODO: Crea un oggetto Car con carModel e numDoors
// TODO: Crea un oggetto Motorcycle con motorcycleModel e hasSidecar
// TODO: Crea un array di riferimenti Vehicle contenente Car e Motorcycle
// TODO: Scorri l'array e, per ogni veicolo:
// 1. Chiama il metodo inspect()
// 2. Usa instanceof per verificare se è un Car, poi esegui il downcast e chiama checkDoors()
// 3. Usa instanceof per verificare se è un Motorcycle, poi esegui il downcast e chiama checkSidecar()
}
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti della programmazione a oggetti
File esterniIntroduzione alla programmazione a oggettiClassi e oggettiLa parola chiave thisMetodiCampi (attributi)Metodo costruttoreSovraccarico dei costruttoriRipasso - Calcolatrice semplice4Ereditarietà
Ereditarietà di base (extends)La parola chiave superSovrascrittura dei metodi (@Override)Concatenamento dei costruttoriLa classe ObjectEreditarietà singola e multilivelloPerché non esiste l'ereditarietà multipla delle classiRiepilogo: gerarchia dei dipendenti7Metodi speciali e classe Object
Metodo toString()equals() e hashCode()Metodo clone()compareTo() e ComparableInterfaccia ComparatorRiepilogo - Ordinamento personalizzato2Modificatori di accesso e incapsulamento
Panoramica dei livelli di accessoMetodi getter e setterNascondimento delle informazioniLa parola chiave finalRiepilogo - Gestore di conti bancari5Polimorfismo
Nozioni di base sull'overloading dei metodiOverride dei metodi (a runtime)Upcasting e downcastingL'operatore instanceofClassi e metodi astrattiRiepilogo - Calcolatore di forme8Concetti avanzati di OOP
Composizione vs ereditarietàAggregazione vs composizioneClassi interne, annidate e anonimeEnum e metodi degli EnumRecord (Java 16+)Classi sealed (Java 17+)11Modelli di progettazione Parte 1
Introduzione ai modelli di progettazionePattern SingletonPattern FactoryPattern BuilderPattern ObserverPattern Strategy3Proprietà di classe e membri statici
Variabili di istanza e staticheMetodi staticiBlocchi staticiCostanti (static final)Riepilogo - Contatore e utility6Interfacce e classi astratte
Introduzione alle interfacceImplementazione delle interfacceImplementazione di più interfacceMetodi default e static nelle interfacceClassi astratte e interfacce a confrontoInterfacce funzionaliRiepilogo: sistema di pagamento9Tipi generici
Introduzione ai tipi genericiClassi genericheMetodi genericiParametri di tipo con limitiCaratteri jolly (?, extends, super)Riepilogo - Contenitore generico12Modelli di progettazione – Parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern CompositePattern IteratorEsercitati da solo: Compilatore Java online