CodeGym /Blog Java /Random-FR /Opérateur instanceof Java
Auteur
Jesse Haniel
Lead Software Architect at Tribunal de Justiça da Paraíba

Opérateur instanceof Java

Publié dans le groupe Random-FR
Salut! Aujourd'hui, nous allons parler de l' opérateur instanceof , examiner des exemples d'utilisation et aborder certains aspects de son fonctionnement :) Vous avez déjà rencontré cet opérateur dans les premiers niveaux de CodeGym. Vous rappelez-vous pourquoi nous en avons besoin ? Sinon, pas de soucis. Rappelons-nous ensemble. L' opérateur instanceof est nécessaire pour vérifier si un objet référencé par une variable X a été créé sur la base d'une classe Y. Cela semble simple. Pourquoi sommes-nous revenus sur ce sujet ? Tout d'abord, parce que maintenant vous connaissez bien le mécanisme d'héritage de Java et les autres principes de la POO. L' opérateur instanceof sera maintenant beaucoup plus clair et nous verrons des exemples plus avancés de son utilisation. Allons-y!Fonctionnement de l'opérateur instanceof - 1Vous vous souvenez probablement que l' opérateur instanceof renvoie true si la vérification est vraie ou false si l'expression est fausse. En conséquence, il se produit généralement dans toutes sortes d'expressions conditionnelles ( if…else ). Commençons par quelques exemples plus simples :

public class Main {

   public static void main(String[] args) {

       Integer x = new Integer(22);

       System.out.println(x instanceof Integer);
   }
}
Selon vous, qu'est-ce qui sera affiché sur la console ? Eh bien, c'est évident ici. :) L' objet x est un Integer, donc le résultat sera true . Sortie console : True Essayons de vérifier s'il s'agit d'une chaîne :

public class Main {

   public static void main(String[] args) {

       Integer x = new Integer(22);

       System.out.println(x instanceof String); // Error!
   }
}
Nous avons une erreur. Et attention : le compilateur a généré l'erreur avant d'exécuter le code ! Il a immédiatement vu que Integer et String ne peuvent pas être automatiquement convertis l'un à l'autre et ne sont pas liés par héritage. Par conséquent, un objet Integer n'est pas créé en fonction de String . C'est pratique et permet d'éviter d'étranges erreurs d'exécution, c'est pourquoi le compilateur nous a aidés ici :) Essayons maintenant de considérer des exemples plus difficiles. Puisque nous avons mentionné l'héritage, travaillons avec le petit système de classes suivant :

public class Animal {

}

public class Cat extends Animal {

}

public class MaineCoon extends Cat {

}
Nous savons déjà comment instanceof se comporte lorsque nous vérifions si un objet est une instance d'une classe, mais que se passe-t-il si nous considérons la relation parent-enfant ? Par exemple, que pensez-vous que ces expressions donneront :

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);

   }
}
Sortie : Vrai Faux La question principale à laquelle il faut répondre est exactement comment instanceof interprète 'objet créé basé sur une classe' ' cat instanceof Animal ' est évalué à true , mais nous pouvons sûrement trouver à redire à cette formulation. Pourquoi un objet Cat est -il créé à partir de la classe Animal ? N'est-il pas créé sur la base de sa propre classe uniquement ? La réponse est assez simple et vous y avez peut-être déjà pensé. Rappelez-vous l'ordre dans lequel les constructeurs sont appelés et les variables sont initialisées lors de la création d'un objet. Nous avons déjà abordé ce sujet dans l'article sur les constructeurs de classe . Voici un exemple tiré de cette leçon :

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");
   }
}
Et si vous l'exécutez dans l'EDI, la sortie de la console ressemblera à ceci : Le constructeur de la classe de base Animal est en cours d'exécution Les variables de la classe Animal ont-elles déjà été initialisées ? Valeur actuelle de la variable statique animalCount = 7700000 Valeur actuelle de brain dans la classe Animal = Valeur initiale de brain dans la classe Animal Valeur actuelle de heart dans la classe Animal = Valeur initiale de heart dans la classe Animal Avoir déjà les variables de la classe Cat été initialisé ? La valeur actuelle de la variable statique catCount = 37 Le constructeur de la classe de base animale est terminé ! Valeur actuelle de brain = Brain Valeur actuelle heart = Heart Le constructeur de la classe cat a démarré (le constructeur Animal est déjà terminé) Valeur actuelle de la variable statique catCount = 37 Valeur actuelle de tail = Valeur initiale de tail dans la classe Cat Valeur actuelle de tail = Queue Vous vous souvenez maintenant ? :) Le constructeur de la classe de base, s'il existe une classe de base, est toujours appelé en premier lors de la création d'un objet. L' opérateur instanceof est guidé par ce principe lorsqu'il essaie de déterminer si un objet A a été créé sur la base d'une classe B. Si le constructeur de la classe de base est appelé, il n'y a aucun doute. Avec la deuxième vérification, tout est plus simple :

System.out.println(cat instanceof MaineCoon);
Le constructeur MaineCoon n'a pas été appelé lors de la création de l' objet Cat , ce qui est logique. Après tout, MaineCoon est un descendant de Cat , pas un ancêtre. Et ce n'est pas un modèle pour Cat . D'accord, je pense que nous sommes clairs là-dessus. Mais que se passe-t-il si nous faisons cela ? :

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... maintenant c'est plus difficile. Parlons-en. Nous avons une variable Cat à laquelle nous avons assigné un objet MaineCoon . Au fait, pourquoi ça marche même ? On peut faire ça, non ? Oui nous pouvons. Après tout, chaque MaineCoon est un chat. Si ce n'est pas tout à fait clair, souvenez-vous de l'exemple d'élargissement des types primitifs :

public class Main {

   public static void main(String[] args) {

       long x = 1024;

   }
}
Le nombre 1024 est un court : il rentre facilement dans une variable longue , puisqu'il y a suffisamment d'octets pour l'accueillir (rappelez-vous l'exemple avec les poupées ?). Un objet descendant peut toujours être affecté à une variable ancêtre. Pour l'instant, rappelez-vous juste ceci, et dans les leçons suivantes, nous analyserons comment cela fonctionne. Alors, que produit notre exemple ?

Cat cat = new MaineCoon();
System.out.println(cat instanceof Cat);
System.out.println(cat instanceof MaineCoon);
Que va vérifier instanceof ? notre variable Cat ou notre objet MaineCoon ? La réponse est que cette question est en fait simple. Il vous suffit de relire la définition de l'opérateur : L' opérateur instanceof est nécessaire pour vérifier si un objet référencé par une variable X a été créé sur la base d'une classe Y. L' opérateur instanceof teste l'origine d'un objet, pas le type de la variable. Ainsi, dans cet exemple, notre programme affichera true dans les deux cas : nous avons un objet MaineCoon . De toute évidence, il a été créé sur la base de la classe MaineCoon , mais il a été créé sur la base du chatclasse parent aussi!
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION