W3docs

L'opérateur instanceof en Java

Testez le type d'un objet à l'exécution avec l'opérateur instanceof et utilisez le filtrage par motif pour instanceof en Java.

instanceof pose une question à l'exécution : « cette référence est-elle vraiment un T (ou un sous-type de T) ? » La réponse est un boolean, et la forme moderne avec filtrage par motif lie également la valeur à une variable typée en une seule étape, éliminant ainsi tout cast séparé.

C'est l'outil que l'on utilise lorsqu'on dispose d'une référence polymorphe et qu'on a besoin de savoir quel type concret elle représente réellement — typiquement dans equals, lors du parcours d'une structure de données hétérogène, ou lorsqu'on travaille avec des hiérarchies scellées.

La forme de base

La syntaxe classique est expression instanceof Type :

Object o = "hello";
if (o instanceof String) {
  String s = (String) o;
  System.out.println(s.length());
}

La vérification retourne true si o référence une String ou tout sous-type, et false si o est null ou pointe vers un autre type d'objet. null instanceof Anything est toujours false — une petite garantie bien utile.

Le filtrage par motif pour instanceof

Depuis Java 16, instanceof accepte un motif de type qui déclare une variable liée au type restreint dans la même expression :

if (o instanceof String s) {
  System.out.println(s.length());   // no cast needed
}

Si la vérification réussit, s est dans la portée et déjà typée comme String. Si elle échoue, s n'est pas dans la portée. Le cast disparaît, la redondance disparaît, et il est impossible de caster accidentellement quelque chose que la vérification a rejeté.

Portée de la variable liée

La variable liée est dans la portée partout où le compilateur peut prouver que la vérification a réussi. Cela inclut la branche if, mais cela se propage aussi à travers && et dans la négation du if :

if (o instanceof String s && s.length() > 3) { ... }   // s is in scope after && — also a String

if (!(o instanceof String s)) return;
System.out.println(s.length());   // s is in scope after the early return

Ce second motif est particulièrement pratique pour le style de code à clause de garde — restreindre le type, sortir si ça ne correspond pas, puis utiliser librement le nom lié en dessous.

En revanche, avec || : la liaison ne se propage pas à travers, car le côté droit s'exécute précisément lorsque la vérification a échoué. o instanceof String s || s.length() > 0 ne compile pas — s n'est pas dans la portée à droite du ||.

Restrictions sur le type cible

Le compilateur rejette les vérifications qu'il peut prouver impossibles. "hello" instanceof Integer ne compile même pas, car String et Integer ne sont pas liés. Cela détecte les fautes de frappe et les restes de refactorisation au moment de la compilation plutôt qu'à l'exécution.

Il rejette également les upcast qui ne peuvent pas échouer : Object o = ...; if (o instanceof Object) {} est signalé comme redondant.

Dans switch

Le même mécanisme de filtrage par motif est disponible dans switch, où il brille vraiment sur les hiérarchies scellées :

String describe(Object o) {
  return switch (o) {
    case Integer i  -> "int " + i;
    case String  s  -> "str of length " + s.length();
    case int[]   a  -> "array of " + a.length;
    case null       -> "nothing";
    default         -> "something else";
  };
}

Avec un type scellé comme sélecteur, vous pouvez supprimer le default et le compilateur exigera un cas pour chaque sous-type autorisé — associez cela aux classes scellées pour obtenir une analyse de cas exhaustive.

Quand l'utiliser — et quand ne pas l'utiliser

Utilisez instanceof lorsque le type est réellement inconnu et que la réponse change le comportement : implémentation de equals, traitement de hiérarchies scellées d'union étiquetée, parcours de nœuds AST. Ne l'utilisez pas comme substitut à un polymorphisme approprié — une chaîne de if (x instanceof A) ... else if (x instanceof B) ... sur une hiérarchie ouverte est généralement le signe qu'une méthode virtuelle sur le type ferait mieux le travail.

Un exemple concret

java— editable, runs on the server

Et ensuite

instanceof est l'une des nombreuses méthodes auxquelles tout objet Java répond. Le chapitre suivant prend du recul pour examiner l'ensemble — java.lang.Object, la classe racine que tout type étend silencieusement, et les méthodes qu'on en hérite que l'on l'ait voulu ou non. Continuer vers La classe Object en Java.

Pratique

Pratique
Que vous évite le filtrage par motif pour `instanceof` (`if (o instanceof String s)`) par rapport à la forme classique ?
Que vous évite le filtrage par motif pour `instanceof` (`if (o instanceof String s)`) par rapport à la forme classique ?
Was this page helpful?