Why can't a “Class” variable be passed to instanceof?

喜欢而已 提交于 2019-11-28 17:41:54

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.

Eyal Schneider

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.

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.

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

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