我试图了解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。
答案 0 :(得分:9)
来自Java语言规范3.0,第15.20.2节:
如果将RelationalExpression转换为ReferenceType 作为编译时错误被拒绝,然后是关系实例 表达式同样会产生编译时错误。在这样的 情况,表达式instanceof的结果永远不会 真。
由于您无法将演员表从HashMap
编译为Date
,因此您无法在两者之间编译instanceof
测试。
答案 1 :(得分:4)
您声明Map m
并使用instanceof
,因为Map
是interface
,新类可以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)