对于接口和类,“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 C
和class 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 C
expression式编译器不能预先判断它是真的还是假的,但是看着obj instanceof A
它知道这总是假的,因此毫无意义,并且帮助你防止错误。 如果你仍然想在你的程序中进行这种无意义的检查,你可以添加一个明确的转换到Object
:
System.out.println(((Object)obj) instanceof A); //compiles fine
通过在下面的类声明中使用final
修饰符,可以确保不存在可以实现Foobar
接口的Test
的子类。 在这种情况下,很明显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
未被声明为final
,那么Test
的子类可能会实现接口。 这就是为什么在这种情况下编译器会允许声明test instanceof Foobar
。