java中的instanceof运算符用于比较不同的类

时间:2012-02-02 06:09:47

标签: java instanceof

我试图了解Java中的instanceof运算符是如何工作的,并且面临着一个非常奇怪的问题。

public static void main(String[] args) {
    Map m = new HashMap();
    System.out.println("m instanceof Date: " + (m instanceof Date));
}

以上按预期返回false。然而,

public static void main(String[] args) {
    HashMap m = new HashMap();
    System.out.println("m instanceof Date: " + (m instanceof Date));
}

这甚至都没有编译。我收到错误

inconvertible types
found   : java.util.HashMap
required : java.util.Date

我在这里缺少什么? 我正在使用IntelliJ Idea 11。

4 个答案:

答案 0 :(得分:9)

来自Java语言规范3.0,第15.20.2节:

  

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

由于您无法将演员表从HashMap编译为Date,因此您无法在两者之间编译instanceof测试。

答案 1 :(得分:4)

您声明Map m并使用instanceof,因为Mapinterface,新类可以extends Date implements Map。其他(不是Date)抽象类或类导致编译错误。

public static void main(String[] args) {
    Map m = new HashMap();
    System.out.println("m instanceof Date: " + (m instanceof Date));
}

答案 2 :(得分:2)

@Bon Espresso几乎在我看来确实说出了正确答案。这是我的小补充:

您必须了解实际的实例,因此定义:

instanceof是一个二元运算符,用于检查实例是否属于某种类型

所以,当你这样做时:

 Map m = new HashMap();

在编译时m实际上是接口,但是针对instanceof的实际测试发生在运行时,实例不是接口,因此编译器无法确定如果实例“后面”m(某个实现此接口的类)实际上是一个可以扩展Date的类。

我的意思是你可以有一个类似这样的宣言的课程:

class MyClass extends Date implements Map{
     .....
}

然后你可以这样做:

 Map myMap = new MyClass();
 (myMap instanceof Date) 

这是完全合法的,因为MyClass实际上扩展了Date。

这里的想法可以看出,如果使用instanceof进行检查的可能性最小,编译器就不会抱怨。

另一方面,在你的第二个例子中:

    HashMap m = new HashMap();

您要声明Map接口的实际实现,或实例。在这种情况下,编译器确保HashMap不会扩展Date,从而为您提供错误。

答案 3 :(得分:0)