下面是一个例子:
public boolean check(Class<?> clazz, Object o)
{
return clazz.isInstance(o);
}
check(int.class, 7); // returns false
由于isInstance
接受Object
,它不适用于int
,因为int
是一个基元类型,并且会自动装箱以Integer
。那么是否可以编写通用检查方法呢?还是我应该确保克拉兹属于Class<? extends Object>
型?
并非所有Class
对象都表示类/引用类型;也有Class
对象表示基元类型。这很有用,因为在对字段和方法使用反射时,通常需要指定它们的类型,并且可以是基元类型。因此Class
用于表示所有此类预泛型类型。
但是,Class
类的许多方法对基元类型没有意义。例如,对象不可能instanceof int
。因此,类似的 .isInstance()
方法将始终返回 false
。由于该方法的参数是类型 Object
,从语言的角度来看,您传入的内容根本不可能是原始类型。
当然,在 Java 5+ 中,当您将原语传递给类型 Object
的参数时,它会经历自动装箱,但它经历了自动装箱的事实意味着传递的内容实际上是对对象的引用。引用类型和基元类型是不同的。参数可以是引用类型或基元类型。因此,您不能编写可以采用"引用或原语"的方法。
在您的示例中,您可能要问的是检测对象是从基元自动装箱的,并将其与基元类型进行比较。但是,无法检测调用方是否将其自动装箱,因为自动装箱是在调用之前发生的完全调用方端操作。
但是,假设它是自动装箱的,您知道它应该转到哪种类型。如果你期待一个int
,并且它被自动装箱并传递给你的方法,它应该是Integer
的实例。因此,您可以做的是,当clazz
表示基元类型时,改为对其包装类执行检查。因此,当它看到clazz
int.class
时,将其替换为 Integer.class
,然后执行检查。请注意,这种方式仍然无法判断作为o
参数传递的内容是否被自动装箱。
Java 中没有int
类。它的Integer
类。 7
转换为Integer.valueOf(7)
,int.class
将根据JLS转换为Integer.class
。
如果
p
是基元类型的名称,则B
装箱转换后p
类型的表达式。然后类型 的p.class
是Class<B>
.
由于Integer
是类对象,而int
是基元类型。因此,大多数Class
方法,如isInstance
、isAssignableFrom
等在int.class
的上下文中都是无效的,因此你会看到这种矛盾。
check(Integer.class, 7);
应该给出预期的结果。