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

时间:2013-04-28 17:20:12

标签: java generics reflection int autoboxing

以下是一个例子:

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>。 那么是否可以编写通用的检查方法?或者我应该确定 clazz的类型为{{1}}?

2 个答案:

答案 0 :(得分:6)

并非所有Class个对象都代表类/引用类型;还有Class个对象代表基本类型。这很有用,因为在使用带有字段和方法的反射时,通常需要指定它们的类型,它可以是基本类型。因此,Class用于表示所有此类pre-generics类型。

然而,Class类的许多方法对于原始类型没有意义。例如,对象不可能是instanceof int。因此,类似的.isInstance()方法将始终返回false。由于该方法的参数是类型Object,因此从语言的角度来看,根本不可能将传递的内容设置为基本类型。

当然,在Java 5+中,当您将基元传递给Object类型的参数时,它会经历自动装箱,但它经历了自动装箱的事实意味着实际传递的内容实际上是对对象的引用。引用类型和基元类型是不同的。参数是引用类型或基本类型。因此,您无法编写可以采用“引用或原语”的方法。

在您的示例中,您可能要问的是检测对象是否从基元自动装箱,并将其与基本类型进行比较。但是,无法检测呼叫者是否自动进行了操作,因为自动装箱是在呼叫之前发生的完全呼叫者操作。

然而,假设它是自动装箱的,你知道应该去哪种类型。如果您期望int,并且它已自动装箱并传递给您的方法,那么它应该是Integer的实例。因此,当clazz表示基本类型时,您可以执行的操作是对其包装类执行检查。因此,当它看到clazzint.class时,请将其替换为Integer.class,然后执行检查。请注意,这种方式仍然无法判断传递的内容是o参数是否已自动装箱。

答案 1 :(得分:3)

Java中没有int类。它的Integer类。 7已转换为Integer.valueOf(7)int.class将根据JLS转换为Integer.class

  

如果p是基本类型的名称,请B为类型   拳击转换后类型p的表达式。然后是类型   p.class的{​​{1}}。{/ p>

由于Class<B>是一个类对象,而Integer是原始类型。因此,int的大多数方法(如ClassisInstance等操作对象在isAssignableFrom的上下文中无效,因此您会看到这种矛盾。

int.class

应该给出预期的结果。