6

这是一个例子:

public boolean check(Class<?> clazz, Object o)
{
    return clazz.isInstance(o);
}

check(int.class, 7); // returns false

由于isInstance接受一个Object,它不会与 一起使用int,因为int它是一个原始类型并且被自动装箱到Integer. 那么是否有可能编写一个通用的检查方法?还是我应该确保 clazz 是 type Class<? extends Object>

4

2 回答 2

6

并非所有Class对象都代表类/引用类型;还有Class代表原始类型的对象。这很有用,因为在对字段和方法使用反射时,您通常需要指定它们的类型,并且它可以是原始类型。SoClass用于表示所有此类预泛型类型。

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.

于 2013-04-29T01:29:09.510 回答
3

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

如果p是原始类型的名称,令是装箱转换后B的类型表达式的类型。p那么 的类型p.classClass<B>

sinceInteger是类对象,whileint是原始类型。因此,对 Objects 进行操作的大多数方法,Class例如isInstance, etc 在 的上下文中都是无效的,因此您会看到这种矛盾。isAssignableFromint.class

check(Integer.class, 7);

应该给出预期的结果。

于 2013-04-28T17:25:06.417 回答