测试 object 是否为参数类型的 instanceof

有没有办法确定一个对象是否是泛型类型的实例?

public <T> test(Object obj) {
if (obj instanceof T) {
...
}
}

这显然行不通。还有别的选择吗?就像我想使用 Java 反射来实例化一个类,然后检查它是否是泛型 T类型。

90651 次浏览

It would make more sense to put the restriction on where the type T is used to parametrise the Class type. When you pass the type in, instead of using something like Class<?>, you should use Class<? extends T>.

The only way you can do this check is if you have the Class object representing the type:

Class<T> type; //maybe passed into the method
if ( type.isInstance(obj) ) {
//...
}

This will only work (partly) if you have an object of type T. Then you can get the class of that object, see java.lang.Class<T> and find if it's the same as the object in question.

But note that this goes counter the very reason we have genrics: using a generic type is a way to say that you don't care what type it really is (up to upper and lower bounds that may be specified).

To extend the sample of Mark Peters, often you want to do something like:

Class<T> type; //maybe passed to the method
if ( type.isInstance(obj) ) {
T t = type.cast(obj);
// ...
}

You could try this,

// Cast your object to the generic type.
T data = null;
try {
data = (T) obj;
} catch (ClassCastException cce) {
// Log the error.
}


// Check if the cast completed successfully.
if(data != null) {
// whatever....
}

If you don't want to pass Class type as a parameter as mentioned by Mark Peters, you can use the following code. Kudos to David O'Meara.

  Class<T> type = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass())
.getActualTypeArguments()[0];
if (type.isInstance(obj)) {
...
}