instanceof编译时错误何时以及为什么?

时间:2013-10-17 13:40:48

标签: java

下面给出的代码编译:

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

为什么会这样?这两种情况都非常相似?

6 个答案:

答案 0 :(得分:2)

因为编译器足够聪明,无法知道实例o可能以任何可能的方式成为Two类。

因此,这个if语句没有意义,因为它总是返回false。

例如,类OneTwo都扩展了基本类Object。你可以这样做:

One one = new One();
Two two = new Two();

Object o1 = one;
Object o2 = two;

if (o1 instanceof One) { ... }

这是有道理的,因为如果你将实例保存到哪个类型是该实例的祖先的变量,那么Object OneTwo或其他{{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)

来自jls-15.20.2

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表达式不正确。另一方面,如果类PointElement的子类。

附注:使用instanceof运算符时,请注意null不是任何实例。