Je voudrais connaître le comportement suivant de l'opérateur instanceof
en Java.
interface C {}
class B {}
public class A {
public static void main(String args[]) {
B obj = new B();
System.out.println(obj instanceof A); //Gives compiler error
System.out.println(obj instanceof C); //Gives false as output
}
}
Pourquoi en est-il ainsi? Il n'y a pas de relation entre interface C
et class B
, mais ça donne faux alors qu'en cas de obj instanceof A
cela donne une erreur de compilation?
Parce que Java n'a pas d'héritage de classes multiples, il est absolument connu lors de la compilation que obj
objet de type B
ne peut pas être un sous-type de A
. On d'autre part cela peut éventuellement être un sous-type d'interface C
, par exemple dans ce cas:
interface C {}
class B {}
class D extends B implements C {}
public class A {
public static void main(String args[]) {
B obj = new D();
System.out.println(obj instanceof C); //compiles and gives true as output
}
}
Donc, en regardant uniquement obj instanceof C
le compilateur d'expressions ne peut pas dire à l'avance si ce sera vrai ou faux, mais en regardant obj instanceof A
il sait que c'est toujours faux, donc vide de sens et vous aide à éviter une erreur. Si vous voulez toujours avoir cette vérification vide de sens dans votre programme, vous pouvez ajouter un casting explicite à Object
:
System.out.println(((Object)obj) instanceof A); //compiles fine
En utilisant le modificateur final
dans la déclaration de classe ci-dessous, il est garanti qu'il ne peut pas y avoir de sous-classe de Test
, qui peut implémenter l'interface Foobar
. Dans ce cas, il est évident que Test
et Foobar
ne sont pas compatibles entre eux:
public final class Test {
public static void main(String[] args) {
Test test = new Test();
System.out.println(test instanceof Foobar); // Compiler error: incompatible types
}
}
interface Foobar {
}
Sinon, si Test
n'est pas déclaré final
, il se peut qu'une sous-classe de Test
implémente l'interface. Et c'est pourquoi le compilateur autoriserait l'instruction test instanceof Foobar
dans ce cas.