问题
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