对于接口和类,“instanceof”操作符的行为不同

我想知道关于Java中instanceof操作符的下面的行为。

 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 } } 

为什么这样? interface Cclass B之间没有关系,但它给出了错误,而在obj instanceof A情况下,它给编译器错误?

由于Java没有多个类inheritance,所以在编译过程中绝对知道typesB obj对象不能是A子types。 另一方面,它可能是接口C子types,例如在这种情况下:

 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 Cexpression式编译器不能预先判断它是真的还是假的,但是看着obj instanceof A它知道这总是假的,因此毫无意义,并且帮助你防止错误。 如果你仍然想在你的程序中进行这种无意义的检查,你可以添加一个明确的转换到Object

 System.out.println(((Object)obj) instanceof A); //compiles fine 

通过在下面的类声明中使用final修饰符,可以确保不存在可以实现Foobar接口的Test的子类。 在这种情况下,很明显TestFoobar不兼容:

 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未被声明为final ,那么Test的子类可能会实现接口。 这就是为什么在这种情况下编译器会允许声明test instanceof Foobar