“instanceof”运算符对于接口和类的行为不同

2022-08-31 11:24:10

我想知道关于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
    }
}

为什么会这样?和 之间没有关系,但它给出 false,而如果它给出编译器错误?interface Cclass Bobj instanceof A


答案 1

因为 Java 没有多类继承,所以在编译期间绝对知道类型的对象不能是 的子类型。另一方面,它可能是接口的子类型,例如在这种情况下:objBAC

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 Cobj instanceof AObject

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

答案 2

通过在下面的类声明中使用修饰符,可以保证不能有 的子类,它可以实现接口。在这种情况下,很明显,并且彼此不兼容:finalTestFoobarTestFoobar

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

否则,如果未声明 ,则 可能是 的子类实现了该接口。这就是为什么编译器在这种情况下允许该语句的原因。TestfinalTesttest instanceof Foobar


推荐