提问者:小点点

'instanceof'运算符对接口和类的行为不同


我想知道关于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的情况下,它给出了编译器错误?


共2个答案

匿名用户

因为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。在这种情况下,很明显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没有声明为最终,则Test的子类可能会实现该接口。这就是为什么编译器在这种情况下允许语句test instanceof Fobar