简体   繁体   English

int.class.isInstance(Object)是一个矛盾吗?

[英]Is int.class.isInstance(Object) a contradiction?

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 . 由于isInstance接受一个Object ,因此它不能与int ,因为int是一个基本类型并被自动装箱到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> 或者我应该确保clazz属于Class<? extends Object> Class<? extends Object> ? Class<? extends Object>

Not all Class objects represent classes / reference types; 并非所有Class对象都表示类/引用类型; there are also Class objects that represent primitive types. 还有表示基本类型的Class对象。 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. 所以Class用于表示所有这些pre-generics类型。

However, many of the methods of the Class class do not make sense for primitive types. 但是, Class类的许多方法对原始类型没有意义。 For example, it is impossible for an object to be instanceof int . 例如,对象不可能是instanceof int Therefore, the analogous .isInstance() method will always return false . 因此,类似的.isInstance()方法将始终返回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. 由于该方法的参数是Object类型,因此从语言的角度来看,传递给它的是原始类型是不可能的。

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. 当然,在Java 5+中,当您将原语传递给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 . 如果您期望一个int ,并且它被自动装箱并传递给您的方法,那么它应该是Integer一个实例。 Thus, what you could do is, when clazz represents a primitive type, instead perform the check on its wrapper class. 因此,您可以做的是,当clazz表示基本类型时,而是对其包装类执行检查。 Thus, when it sees that clazz is int.class , substitute it with Integer.class , and then perform the check. 因此,当它看到clazzint.class ,用Integer.class替换它,然后执行检查。 Note that this way still doesn't tell whether what was passed as the o parameter was autoboxed. 请注意,这种方式仍然无法判断作为o参数传递的内容是否已自动装箱。

There is no int class in Java. Java中没有int类。 Its Integer class. 它的Integer类。 7 is converted to Integer.valueOf(7) , and int.class will be converted to Integer.class as per JLS. 7将转换为Integer.valueOf(7) ,并且int.class将根据JLS转换为Integer.class

If p is the name of a primitive type, let B be the type of an expression of type p after boxing conversion. 如果p是基本类型的名称,则让B为拳击转换后类型p的表达式的类型。 Then the type of p.class is Class<B> . 那么p.class的类型是Class<B>

Since Integer is a class object, while int is primitive type. 由于Integer是一个类对象,而int是原始类型。 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. 因此,大多数Class方法,如isInstanceisAssignableFrom等操作对象在int.class的上下文中都是无效的,因此你会看到这种矛盾。

check(Integer.class, 7);

should give expected result. 应给出预期的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM