Here's an example:
public boolean check(Class<?> clazz, Object o)
{
return clazz.isInstance(o);
}
check(int.class, 7); // returns false
Since isInstance
accepts an Object
, it won't work with int
, because int
is a primitive type and gets autoboxed to Integer
.
So is it at all possible to write a generic check method? Or should I make sure that
clazz is of type Class<? extends Object>
?
Not all
Class
objects represent classes / reference types; there are alsoClass
objects that represent primitive types. This is useful because in using reflection with fields and methods, you often need to specify their type, and it can be a primitive type. SoClass
is used to represent all such pre-generics types.However, many of the methods of the
Class
class do not make sense for primitive types. For example, it is impossible for an object to beinstanceof int
. Therefore, the analogous.isInstance()
method will always returnfalse
. Since the parameter of that method is typeObject
, it is simply impossible from a language point of view for what you pass in there to be of a primitive type.Sure, in Java 5+ when you pass a primitive to a parameter of type
Object
, it undergoes autoboxing, but the fact that it underwent autoboxing means that what was passed is actually a reference to an object. Reference types and primitive types are distinct. A parameter is either a reference type or primitive type. Thus you cannot write a method that can take a "reference or primitive".What you may be asking, in your example, is to detect that the object was autoboxed from a primitive, and compare it to a primitive type. However, it is impossible to detect whether the caller autoboxed it, since autoboxing is a completely caller-side operation that happens before the call.
However, assuming it was autoboxed, you know what type it should have gone to. If you are expecting an
int
, and it is autoboxed and passed to your method, it should be an instance ofInteger
. Thus, what you could do is, whenclazz
represents a primitive type, instead perform the check on its wrapper class. Thus, when it sees thatclazz
isint.class
, substitute it withInteger.class
, and then perform the check. Note that this way still doesn't tell whether what was passed as theo
parameter was autoboxed.There is no
int
class in Java. ItsInteger
class.7
is converted toInteger.valueOf(7)
, andint.class
will be converted toInteger.class
as per JLS.Since
Integer
is a class object, whileint
is primitive type. So, most methods ofClass
such asisInstance
,isAssignableFrom
etc which operates on Objects are invalid in the context ofint.class
, hence you see that contradiction.should give expected result.