Why doesn\'t this code compile?
public boolean isOf(Class clazz, Object obj){
if(obj instanceof clazz){
return true;
}else{
instanceof
can be used only with explicit class names (stated at compile time). In order to do a runtime check, you should do:
clazz.isInstance(obj)
This has a small advantage over clazz.isAssignableFrom(..)
since it deals with the case obj == null
better.
The instanceof
operator works on reference types, like Integer
, and not on objects, like new Integer(213)
. You probably want something like
clazz.isInstance(obj)
Side note: your code will be more concise if you write
public boolean isOf(Class clazz, Object obj){
return clazz.isInstance(obj)
}
Not really sure if you need a method anymore ,though.
As others have mentioned, you cannot pass a class variable to instanceof
because a class variable references an instance of an Object, while the right hand of instanceof
has to be a type. That is, instanceof
does not mean "y is an instance of Object x", it means "y is an instance of type X". In case you don't know the difference between an Object and a type, consider:
Object o = new Object();
Here, the type is Object
, and o
is a reference to the instance of the Object with that type. Thus:
if(o instanceof Object)
is valid but
if(o instanceof o)
is not because o
on the right hand side is an Object, not a type.
More specific to your case, a class instance is not a type, it is an Object (which is created for you by the JVM). In your method, Class
is a type, but clazz
is an Object (well, a reference to an Object)
What you need is an way to compare an Object to a Class Object. It turns out that this is popular so this is provided to you as a method of the Class Object: isInstance()
.
Here is the Java Doc for isInstance, which explains this better:
public boolean isInstance(Object obj)
Determines if the specified Object is assignment-compatible with the object represented by this Class. This method is the dynamic equivalent of the Java language instanceof operator. The method returns true if the specified Object argument is non-null and can be cast to the reference type represented by this Class object without raising a ClassCastException. It returns false otherwise.
Specifically, if this Class object represents a declared class, this method returns true if the specified Object argument is an instance of the represented class (or of any of its subclasses); it returns false otherwise. If this Class object represents an array class, this method returns true if the specified Object argument can be converted to an object of the array class by an identity conversion or by a widening reference conversion; it returns false otherwise. If this Class object represents an interface, this method returns true if the class or any superclass of the specified Object argument implements this interface; it returns false otherwise. If this Class object represents a primitive type, this method returns false.
Parameters: obj - the object to check
Returns: true if obj is an instance of this class
Since: JDK1.1
Firstly, instanceof
requires that the operand on the right is an actual class (e.g. obj instanceof Object
or obj instanceof Integer
) and not a variable of type Class
. Secondly, you have made a fairly common newbie mistake that you really should not do... the following pattern:
if ( conditional_expression ){ return true; } else{ return false; }
The above can be refactored into:
return conditional_expression;
You should always perform that refactoring, as it eliminates a redundant if...else statement. Similarly, the expression return conditional_expression ? true : false;
is refactorable to the same result.