为什么在此instanceof测试中存在编译器错误

时间:2013-10-01 12:34:33

标签: java

我认为以下代码会编译并打印“No”

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

但它给我一个编译错误,说明inconvertible types 不应该instanceof运算符检查对象是否在继承层次结构中,如果是,则返回true,如果不是,则返回false

修改

如果是编译器已经知道某个条件永远不会为真并抛出编译器错误的原因,为什么这个代码编译

if(false) {
  System.out.println("Yes");
}

4 个答案:

答案 0 :(得分:4)

您收到该消息是因为编译器能够告诉o不能是Two的实例,因为类OneTwo没有继承关系。

也许你打算写:

Object o = new One();

在这种情况下,你的测试会有意义。

答案 1 :(得分:4)

我相信这是因为您已将“o”变量声明为“One”类型。 将您的代码更改为此代码,它应该编译

   Object o = new One();
   if(o instanceof Two) {
     System.out.println("Yes");
   } else {
     System.out.println("No");
   }

当您事先不知道类型时,将使用instanceof运算符。因此,当您有一个通过方法参数传入的对象时,或者您的变量是使用基类的类型声明并且希望每个子类类型具有不同的行为时。在您提供的场景中,编译器可以在编译时告诉您所写的内容永远不会成立,并且这样做。

编辑:if(false)编译,因为很多人都使用这样的模式:

public class Application{

    private static final boolean DEBUG = true;

    public static void main(String args[]){
        if(DEBUG){
            System.out.println("Debugging information");
        }
    }
}

现在假设一个大型应用程序,这种模式在几个地方重复出现。如果编译器拒绝编译它,那么从DEBUG模式切换到DEBUG模式会更加困难。

在我之前的解释中,也许我不应该使用“编译器可以在编译时告诉你你写的内容永远不会是真的”。更好的描述是“编译器可以告诉您正在编写的内容没有意义”。

答案 2 :(得分:0)

instanceof用于标识由另一个类的引用变量多态引用的对象,因此如果引用变量o无法引用类Two的对象,则它赢得& #39; t compile。

所以这个:

One o = new One();
if(o instanceof Two) {
    System.out.println("ok");
}

作为一个例子,将是一个类似于此的错误:

int i = 1;
if (i == "s") {
    System.out.println("ok");
}

根本无法编译!

修改

多态性的一个例子,它会使你的代码编译(根据其他人的答案):

Object o = new One();

因为o 可以引用Two,所以instanceof会告诉您它是否有效。

答案 3 :(得分:-1)

首先,对于上述程序,您将获得“不兼容的条件操作数类型一和二”,因为一和二没有任何关系。

要使上面的程序结果为True,它应该是,

public class One {
    public static void main(String[] args) {

        One o = new Two();
        if (o instanceof Two) {
            System.out.println("Yes");
        } else {
            System.out.println("No");
        }
    }
}

class Two extends One {
}

这里,一个是父母,两个是孩子。父级引用子对象,运算符的实例将返回true。