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

时间:2015-07-14 05:39:44

标签: java class inheritance interface 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的情况下它给出了编译错误?

2 个答案:

答案 0 :(得分:127)

因为Java没有多类继承,所以在编译过程中绝对知道类型obj的{​​{1}}对象不能是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添加显式强制转换:

Object

答案 1 :(得分:1)

通过在下面的类声明中使用final修饰符,可以保证不能成为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未声明为final,则Test的子类可能会实现该接口。这就是编译器在这种情况下允许语句test instanceof Foobar的原因。