'instanceof' 运算符对于接口和 类 的行为不同
The 'instanceof' operator behaves differently for interfaces and classes
我想知道 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
之间没有关系,但它给出 false 而在 obj instanceof A
的情况下它给出编译器错误?
因为 Java 没有多重 class 继承,所以在编译期间绝对知道 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
它知道这总是假的,因此没有意义并帮助你防止错误。如果您仍然希望在您的程序中进行这种无意义的检查,您可以向 Object
:
添加一个显式转换
System.out.println(((Object)obj) instanceof A); //compiles fine
通过在下面的class声明中使用final
修饰符,保证不会有Test
的subclass,它可以实现界面 Foobar
。在这种情况下,很明显 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
未声明 [=11=],则 Test
的子 class 可能会实现该接口。这就是编译器在这种情况下允许语句 test instanceof Foobar
的原因。
我想知道 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
之间没有关系,但它给出 false 而在 obj instanceof A
的情况下它给出编译器错误?
因为 Java 没有多重 class 继承,所以在编译期间绝对知道 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
它知道这总是假的,因此没有意义并帮助你防止错误。如果您仍然希望在您的程序中进行这种无意义的检查,您可以向 Object
:
System.out.println(((Object)obj) instanceof A); //compiles fine
通过在下面的class声明中使用final
修饰符,保证不会有Test
的subclass,它可以实现界面 Foobar
。在这种情况下,很明显 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
未声明 [=11=],则 Test
的子 class 可能会实现该接口。这就是编译器在这种情况下允许语句 test instanceof Foobar
的原因。