instanceof operator in java for comparing different classes

醉酒当歌 提交于 2019-12-17 20:08:37

问题


I was trying to see how instanceof operator in Java works and am facing a very odd issue.

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

The above returns false as expected. However,

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

This does not even compile. I get an error

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

What am I missing here? I am using IntelliJ Idea 11.


回答1:


From the Java Language Specification 3.0, section 15.20.2:

If a cast of the RelationalExpression to the ReferenceType would be rejected as a compile-time error, then the instanceof relational expression likewise produces a compile-time error. In such a situation, the result of the instanceof expression could never be true.

Since you can't compile a cast from a HashMap to a Date, you can't compile an instanceof test between the two either.




回答2:


You declare a Map m and use instanceof because Map is an interface which is new class can extends Date implements Map. Other (not Date) abstract class or class cause compile error.

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



回答3:


@Bon Espresso almost did say the right answer in my opinion. And here is my small adding to it:

You have to understand what instanceof really does, thus the definition:

instanceof is a binary operator that checks if an instance is of a certain type

So, when you do this:

 Map m = new HashMap();

At compile-time m is actually an interface, but the actual test against instanceof happens at runtime with an instance NOT an interface, thus the compiler can not be sure if the instance "behind" m (some class that implements this interface) is actually a class that could extend Date.

I mean you could have a class with a Declaration like this:

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

And you could then do this:

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

and it would be perfectly legal, because MyClass actually extends Date.

The idea here as you can see, that if there is the smallest chance that the check with instanceof will succeed, the compiler will not complain.

On the other hand in your second example:

    HashMap m = new HashMap();

You are declaring an actual implementation of the Map interface, or an instance. In this case the compiler is sure that HashMap does not extend Date, thus giving you the error.




回答4:


Please refer to JLS spec mentioned over here http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.20.2.

This has been answered very well here instanceof - incompatible conditional operand types



来源:https://stackoverflow.com/questions/9107895/instanceof-operator-in-java-for-comparing-different-classes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!