下面给出的代码编译:
class Robot { }
interface Animal { }
class Feline implements Animal { }
public class BarnCat extends Feline {
public static void main(String[] args) {
Animal af = new Feline();
Feline ff = new Feline();
BarnCat b = new BarnCat();
Robot r = new Robot();
if(af instanceof Animal) System.out.print("1 ");
if(af instanceof BarnCat) System.out.print("2 ");
if(b instanceof Animal) System.out.print("3 ");
if(ff instanceof BarnCat) System.out.print("4 ");
if(r instanceof Animal) System.out.print("5 ");
}
}
这个会抛出编译时错误
public class One{
public static void main(String[] args) {
One o = new One();
if(o instanceof Two) {
System.out.println("Yes");
} else {
System.out.println("No");
}
}
}
class Two{}
为什么会这样?这两种情况都非常相似?
答案 0 :(得分:2)
因为编译器足够聪明,无法知道实例o
可能以任何可能的方式成为Two
类。
因此,这个if
语句没有意义,因为它总是返回false。
例如,类One
和Two
都扩展了基本类Object
。你可以这样做:
One one = new One();
Two two = new Two();
Object o1 = one;
Object o2 = two;
if (o1 instanceof One) { ... }
这是有道理的,因为如果你将实例保存到哪个类型是该实例的祖先的变量,那么Object
One
或Two
或其他{{1}}是不是绝对清楚类
答案 1 :(得分:1)
instanceof
在运行时进行检查。但是,编译器可以在编译时告诉这不是真的,它很聪明:)
请参阅15.20.2. Type Comparison Operator instanceof:
如果将RelationalExpression转换为ReferenceType 作为编译时错误被拒绝,然后是关系实例 表达式同样会产生编译时错误。在这样的 情况,表达式的结果永远不会成真。
答案 2 :(得分:1)
对象o
不可能是instanceof
类二。如果Two extends One
则编译错误将被修复。
答案 3 :(得分:0)
o
的静态类型已知为One
。编译器知道One
对象不能 Two
个对象(因为Two
是"另一个层次结构)。
如果Two
的接口或类派生自One
,
答案 4 :(得分:0)
第二类与第一类无关是任何一种方式。第一类和第二类之间不存在共同的接口或继承关系。因此它会引发异常。
答案 5 :(得分:0)
instanceof
运算符的RelationalExpression操作数的类型必须是引用类型或null类型;否则,发生编译时错误。
如果在instanceof运算符之后提到的ReferenceType不表示可重新生成的引用类型(第4.7节),那么这是一个编译时错误。
如果将RelationalExpression转换为ReferenceType将作为编译时错误被拒绝,则instanceof
关系表达式同样会产生编译时错误。在这种情况下,instanceof
表达式的结果永远不会成立。
class Point { int x, y; }
class Element { int atomicNumber; }
class Test {
public static void main(String[] args) {
Point p = new Point();
Element e = new Element();
if (e instanceof Point) { // compile-time error (you are checking o instanceof Two)
System.out.println("I get your point!");
p = (Point)e; // compile-time error
}
}
}
此程序导致两个编译时错误。转换(Point)e
是不正确的,因为没有Element的实例或其任何可能的子类(这里没有显示)可能是Point的任何子类的实例。由于完全相同的原因,instanceof
表达式不正确。另一方面,如果类Point
是Element
的子类。
附注:使用instanceof
运算符时,请注意null
不是任何实例。