我想知道关于instanceof
运算符在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
}
}
为什么会这样?接口C
和类B
之间没有关系,但它给出了false,而在obj instanceof A
的情况下,它给出了编译器错误?
因为Java没有多类继承,所以在编译过程中绝对知道obj
类型为B
的对象不能是A
的子类型。另一方面,它可能是接口C
的子类型,例如在这种情况下:
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
}
}
所以只看obj instanceof C
表达式编译器不能提前判断它是真是假,但是看obj instanceof A
它知道这总是假的,因此毫无意义,并帮助你防止错误。如果你仍然想在你的程序中进行这种无意义的检查,你可以在对象
中添加一个显式的强制转换:
System.out.println(((Object)obj) instanceof A); //compiles fine
通过在下面的类声明中使用最终
修饰符,可以保证不存在Test
的子类,它可以实现接口foobar
。在这种情况下,很明显Test
和foobar
是不兼容的:
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 {
}
否则,如果Test
没有声明为最终
,则Test
的子类可能会实现该接口。这就是为什么编译器在这种情况下允许语句test instanceof Fobar
。