0

下面给出的代码编译:

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

为什么会这样?这两种情况在性质上颇为相似?

4

6 回答 6

3

instanceof运行时进行检查。但是,编译器可以在编译时判断这不是真的,它很聪明:)

15.20.2。类型比较运算符 instanceof

如果将 RelationalExpression 转换为 ReferenceType 将作为编译时错误被拒绝,则 instanceof 关系表达式同样会产生编译时错误。在这种情况下,instanceof 表达式的结果永远不会为真。

于 2013-10-17T13:47:02.037 回答
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) { ... }

这是有道理的,因为如果您将实例保存到变量中,哪个类型是该实例的祖先,则不是绝对清楚,如果那ObjectOneTwo或任何其他类

于 2013-10-17T13:46:57.497 回答
1

对象不可能oinstanceof二类。如果Two extends One那么编译错误将被修复。

于 2013-10-17T13:48:17.847 回答
0

静态类型o已知为One. 编译器知道一个One对象不能是一个Two对象(因为Two是“另一个层次结构”)。

如果接口或类派生自.TwoOne

于 2013-10-17T13:47:44.287 回答
0

类二与类一没有任何关系。类一和类二之间不存在共同的接口或继承关系,因此会抛出异常。

于 2013-10-17T13:47:51.977 回答
0

jls-15.20.2

运算符的RelationalExpression操作数的instanceof类型必须是引用类型或者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不是任何事物的实例。

于 2013-10-17T13:49:46.040 回答