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

java中用于比较不同类的instanceof运算符,java,instanceof,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) { HashM

我试图了解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。

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

如果将RelationalExpression强制转换为ReferenceType 作为编译时错误被拒绝,然后 表达式同样会产生编译时错误。以这样的方式 在这种情况下,instanceof表达式的结果永远无法 对


由于您无法编译从
HashMap
Date
的强制转换,您也不能在两者之间编译
instanceof
测试。

您声明
映射m
并使用
instanceof
,因为
映射
是一个
接口
,它是一个新类,可以
扩展日期实现映射
。其他(非日期)抽象类或类导致编译错误

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

请参考此处提到的JLS规范


这在这里得到了很好的回答

@在我看来,Bon Espresso几乎说了正确的答案。下面是我的小补充:

您必须了解instanceof的真正功能,因此定义:

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

因此,当您这样做时:

 Map m = new HashMap();
在编译时,m实际上是一个接口,但对instanceof的实际测试发生在运行时,实例不是接口,因此编译器无法确定m后面的实例(实现此接口的某个类)是否真的是一个可以扩展日期的类

我的意思是你可以有一个这样声明的类:

class MyClass extends Date implements Map{
     .....
}
然后你可以这样做:

 Map myMap = new MyClass();
 (myMap instanceof Date) 
这将是完全合法的,因为MyClass实际上延长了日期

正如您所看到的,这里的想法是,如果instanceof检查成功的可能性最小,编译器不会抱怨

另一方面,在第二个示例中:

    HashMap m = new HashMap();

您正在声明映射接口的实际实现,或实例。在这种情况下,编译器确信HashMap不会延长日期,因此会给您带来错误。

完全同意……当我在编译器中尝试相同的方法时,发现了这一点……必须说您已经非常优雅地将其放置了:)