Java中的instanceof运算符用于比较不同类之间的差异。

10

我正在尝试了解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个回答

10

在Java语言规范3.0的第15.20.2节中:

如果将RelationalExpression强制转换为ReferenceType时被拒绝作为编译时错误,则instanceof关系表达式也会产生编译时错误。在这种情况下,instanceof表达式的结果永远不能为真。

由于无法编译从HashMap到Date的转换,因此两者之间也无法进行instanceof测试。


4
您声明一个 Map m 并使用 instanceof,因为 Map 是一个 接口,新类可以通过 extends Date implements Map 实现。其他(非 Date)抽象类或类会导致编译错误。
public static void main(String[] args) {
    Map m = new HashMap();
    System.out.println("m instanceof Date: " + (m instanceof Date));
}

3

@Bon Espresso几乎说对了我的看法。这是我对此的小补充:

你必须理解instanceof实际上做了什么,因此有以下定义:

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,因此会出现错误。


完全同意...当我在编译器中尝试相同的事情时,也发现了这一点...必须说你表达得非常优雅 :) - Ankit Dhingra


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接