1

我认为下面的代码会编译并打印“否”

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检查对象是否在继承层次结构中,如果是则返回truefalse如果不是

编辑:

如果是编译器已经知道某个条件永远不会为真并且引发编译器错误的情况,那么为什么要编译此代码

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

4 回答 4

4

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

也许你的意思是写:

Object o = new One();

在这种情况下,您的测试将是有意义的。

于 2013-10-01T12:39:09.673 回答
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 模式之间切换会更加困难。

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

于 2013-10-01T12:39:14.677 回答
0

instanceof用于标识由另一个类的引用变量多态引用的对象,因此如果引用变量o不能引用类的对象,Two它将无法编译。

所以这:

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会告诉你是否可以。

于 2013-10-01T12:56:14.293 回答
-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。

于 2013-10-01T12:55:13.163 回答