Menu
Coddy logo textTech

L'opérateur instanceof

Fait partie de la section Programmation Orientée Objet du Journey Java de Coddy — leçon 31 sur 87.

La leçon précédente a montré que le transtypage descendant (downcasting) peut échouer avec une ClassCastException si l'objet n'est pas réellement du type vers lequel vous effectuez le transtypage. L'opérateur instanceof résout ce problème en vous permettant de vérifier le type d'un objet avant le transtypage.

La syntaxe est simple : object instanceof ClassName renvoie true si l'objet est une instance de cette classe (ou de l'une de ses sous-classes) :

Animal animal = new Dog();

if (animal instanceof Dog) {
    Dog dog = (Dog) animal;
    dog.bark();  // Appel sécurisé des méthodes spécifiques à Dog
}

Cette vérification évite les erreurs d'exécution en garantissant que le transtypage réussira. L'opérateur renvoie également true pour les types parents dans la hiérarchie :

Dog dog = new Dog();
System.out.println(dog instanceof Dog);     // true
System.out.println(dog instanceof Animal);  // true
System.out.println(dog instanceof Object);  // true

Depuis Java 16, vous pouvez combiner la vérification et le transtypage en une seule étape en utilisant le filtrage par motif (pattern matching) :

if (animal instanceof Dog dog) {
    dog.bark();  // 'dog' est déjà transtypé et prêt à l'emploi
}

Cette syntaxe plus concise élimine la ligne de transtypage (cast) séparée. Notez que instanceof retourne false lorsqu'il est testé par rapport à null, vous n'avez donc pas besoin d'une vérification de nullité séparée.

challenge icon

Défi

Facile

Construisons un système d'inspection de véhicules qui utilise l'opérateur instanceof pour identifier et gérer en toute sécurité différents types de véhicules. Vous allez créer une hiérarchie de véhicules et écrire du code qui vérifie le type réel de chaque véhicule avant d'accéder à ses fonctionnalités spécialisées.

Vous organiserez votre code sur quatre fichiers :

  • Vehicle.java : Créez la classe de base que tous les véhicules partagent. Chaque véhicule possède un champ model (String). Incluez un constructeur pour l'initialiser, une méthode getter getModel(), et une méthode inspect() qui affiche : "Inspecting vehicle: " + model
  • Car.java : Créez une classe qui étend Vehicle. Les voitures ont un champ supplémentaire numDoors (int). Utilisez super pour l'initialisation du parent. Ajoutez une méthode checkDoors() qui affiche : getModel() + " has " + numDoors + " doors"
  • Motorcycle.java : Créez une autre classe qui étend Vehicle. Les motos ont un champ hasSidecar (boolean). Ajoutez une méthode checkSidecar() qui affiche soit getModel() + " has a sidecar" soit getModel() + " has no sidecar" selon la valeur booléenne.
  • Main.java : C'est ici que instanceof devient essentiel ! Vous recevrez quatre entrées : un modèle de voiture, le nombre de portes, un modèle de moto, et si elle a un side-car (true/false).

    Créez un tableau de références Vehicle contenant une Car et une Motorcycle. Ensuite, parcourez le tableau et pour chaque véhicule :

    • Appelez la méthode de base inspect()
    • Utilisez instanceof pour vérifier s'il s'agit d'une Car - si c'est le cas, effectuez un downcast sécurisé et appelez checkDoors()
    • Utilisez instanceof pour vérifier s'il s'agit d'une Motorcycle - si c'est le cas, effectuez un downcast sécurisé et appelez checkSidecar()

Vous recevrez quatre entrées : le modèle de la voiture (String), le nombre de portes (int), le modèle de la moto (String), et si elle a un side-car (boolean).

Votre sortie devrait afficher quatre lignes - pour chaque véhicule, vous verrez son message d'inspection suivi de son test spécifique au type. L'opérateur instanceof garantit que vous n'appelez les méthodes de Car que sur des objets Car réels et les méthodes de Motorcycle sur des objets Motorcycle réels, évitant ainsi toute ClassCastException !

Aide-mémoire

L'opérateur instanceof vérifie si un objet est une instance d'une classe spécifique avant d'effectuer un transtypage (casting) :

Animal animal = new Dog();

if (animal instanceof Dog) {
    Dog dog = (Dog) animal;
    dog.bark();  // Appel sécurisé des méthodes spécifiques à Dog
}

L'opérateur renvoie true pour la classe de l'objet et toutes les classes parentes dans la hiérarchie :

Dog dog = new Dog();
System.out.println(dog instanceof Dog);     // true
System.out.println(dog instanceof Animal);  // true
System.out.println(dog instanceof Object);  // true

Depuis Java 16, le filtrage par motif (pattern matching) combine la vérification et le transtypage en une seule étape :

if (animal instanceof Dog dog) {
    dog.bark();  // 'dog' est déjà transtypé et prêt à l'emploi
}

L'opérateur instanceof renvoie false lorsqu'il est testé par rapport à null, ce qui élimine le besoin de vérifications de nullité séparées.

Essayez vous-même

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Lire les entrées
        String carModel = scanner.nextLine();
        int numDoors = Integer.parseInt(scanner.nextLine());
        String motorcycleModel = scanner.nextLine();
        boolean hasSidecar = Boolean.parseBoolean(scanner.nextLine());
        
        // TODO: Créer un objet Car avec carModel et numDoors
        
        // TODO: Créer un objet Motorcycle avec motorcycleModel et hasSidecar
        
        // TODO: Créer un tableau de références Vehicle contenant la Car et la Motorcycle
        
        // TODO: Parcourir le tableau et pour chaque véhicule :
        // 1. Appeler la méthode inspect()
        // 2. Utiliser instanceof pour vérifier s'il s'agit d'une Car, puis effectuer un downcast et appeler checkDoors()
        // 3. Utiliser instanceof pour vérifier s'il s'agit d'une Motorcycle, puis effectuer un downcast et appeler checkSidecar()
    }
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet