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>
?
The type int[] is a subclass of Object that has all the method from Object . Although syntactically it looks different from other object types (e.g. the name has a primitive type listed in it and there's no class definition), the Java language does consider them objects.
The isInstance() method of java. lang. Class class is used to check if the specified object is compatible to be assigned to the instance of this Class. The method returns true if the specified object is non-null and can be cast to the instance of this Class.
The Integer class is a wrapper for integer values. In Java, integers are not objects and most of the Java utility classes require the use of objects. Thus, if you needed to store an integer in a hashtable, you would have to "wrap" an Integer instance around it.
The java “instanceof” operator is used to test whether the object is an instance of the specified type (class or subclass or interface). It is also known as type comparison operator because it compares the instance with type. It returns either true or false.
Not all Class
objects represent classes / reference types; there are also Class
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. So Class
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 be instanceof int
. Therefore, the analogous .isInstance()
method will always return false
. Since the parameter of that method is type Object
, 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 of Integer
. Thus, what you could do is, when clazz
represents a primitive type, instead perform the check on its wrapper class. Thus, when it sees that clazz
is int.class
, substitute it with Integer.class
, and then perform the check. Note that this way still doesn't tell whether what was passed as the o
parameter was autoboxed.
There is no int
class in Java. Its Integer
class. 7
is converted to Integer.valueOf(7)
, and int.class
will be converted to Integer.class
as per JLS.
If
p
is the name of a primitive type, letB
be the type of an expression of typep
after boxing conversion. Then the type ofp.class
isClass<B>
.
Since Integer
is a class object, while int
is primitive type. So, most methods of Class
such as isInstance
, isAssignableFrom
etc which operates on Objects are invalid in the context of int.class
, hence you see that contradiction.
check(Integer.class, 7);
should give expected result.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With