Is int.class.isInstance (Object) a contradiction?

Here is an example:

public boolean check(Class<?> clazz, Object o) { return clazz.isInstance(o); } check(int.class, 7); // returns false 

Since isInstance accepts Object , it will not work with int , because int is a primitive type and gets autoboxed before Integer . So what can you write a general verification method? Or should I make sure that clazz is of type Class<? extends Object> Class<? extends Object> ?

+6
source share
2 answers

Not all Class objects represent classes / reference types; there are also Class objects, which are primitive types. This is useful because when using reflection with fields and methods, you often need to specify their type, and it can be a primitive type. Thus, Class used to represent all such types before generics.

However, many methods of the Class class do not make sense for primitive types. For example, it is not possible for an object to be instanceof int . Therefore, a similar .isInstance() method will always return false . Since the parameter of this method is an Object type, from a language point of view, it is simply not possible for you to pass there with a primitive type.

Of course, in Java 5+, when you pass a primitive to a parameter of type Object , it undergoes auto-boxing, but the fact that it passed auto-boxing means that what was passed is actually a reference to the object. Link types and primitive types are different. A parameter is either a reference type or a primitive type. Thus, you cannot write a method that can accept a "link or primitive".

In your example, you may be asked to find that the object was autoboxed from a primitive and compare it with a primitive type. However, it is not possible to determine whether the caller has been auto-boxed, since auto-boxing is the full caller, which runs before the call.

However, considering that it is an autobox, you know what type he had to go to. If you expect an int and it is autoboxing and passed to your method, it should be an Integer instance. Thus, what can you do when clazz represents a primitive type, instead check for its wrapper class. That way, when he sees that clazz is int.class , replace it with Integer.class , and then check. Note that this method still does not determine if what was passed as parameter o was passed.

+6
source

There is no int class in Java. Its class is Integer . 7 converted to Integer.valueOf(7) , and int.class converted to Integer.class according to JLS.

If p is the name of a primitive type, let B be a type expression of type p after the box conversion. Then the type of p.class is Class<B> .

Since Integer is a class object, and int is a primitive type. Thus, most Class methods, such as isInstance , isAssignableFrom , etc., that work with objects, are not valid in the context of int.class , so you see this contradiction.

 check(Integer.class, 7); 

should give the expected result.

+2
source

Source: https://habr.com/ru/post/943826/


All Articles