问题是什么
开发中经常会用到范型配合设计模式来封装相同的代码逻辑。但是在具体的代码实现中,有可能需要去获取范型的具体类型Class来处理(比如反射操作),如何在代码中获取到范型的具体类型呢?
获取范型的具体类型
/**
* 获取 T.class
*/
protected Class<P> getTClass() {
return (Class<P>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
getlClass()
/**
* Returns the runtime class of this {@code Object}. The returned
* {@code Class} object is the object that is locked by {@code
* static synchronized} methods of the represented class.
*
* <p><b>The actual result type is {@code Class<? extends |X|>}
* where {@code |X|} is the erasure of the static type of the
* expression on which {@code getClass} is called.</b> For
* example, no cast is required in this code fragment:</p>
*
* <p>
* {@code Number n = 0; }<br>
* {@code Class<? extends Number> c = n.getClass(); }
* </p>
*
* @return The {@code Class} object that represents the runtime
* class of this object.
* @jls 15.8.2 Class Literals
*/
public final native Class<?> getClass();
这里是获取当前类的Class。注意这里返回的是Class
getGenericSuperclass()
public Type getGenericSuperclass() {
ClassRepository info = getGenericInfo();
if (info == null) {
return getSuperclass();
}
// Historical irregularity:
// Generic signature marks interfaces with superclass = Object
// but this API returns null for interfaces
if (isInterface()) {
return null;
}
return info.getSuperclass();
}
这里是获取父类的Class,包含范型参数,注意这里返回的Type。后面会讲Class和Type的区别,(ParameterizedType) getClass().getGenericSuperclass()代码中这里的Type会强转为ParameterizedType。ParameterizedType 表示参数化范型,这里是类似List<T> 或者
AbstractExcelImportService<P>(其中AbstractExcelImportService是代码里的自定义类)
getActualTypeArguments()
/**
* Returns an array of {@code Type} objects representing the actual type
* arguments to this type.
*
* <p>Note that in some cases, the returned array be empty. This can occur
* if this type represents a non-parameterized type nested within
* a parameterized type.
*
* @return an array of {@code Type} objects representing the actual type
* arguments to this type
* @throws TypeNotPresentException if any of the
* actual type arguments refers to a non-existent type declaration
* @throws MalformedParameterizedTypeException if any of the
* actual type parameters refer to a parameterized type that cannot
* be instantiated for any reason
* @since 1.5
*/
Type[] getActualTypeArguments();
这里是返回ParameterizedType中的<>里面的具体参数类型,比如List<T>这里会返回T的具体类型;AbstractExcelImportService<P>这里会返回P的具体类型;Map<K,V>这里会返回K和V的具体类型,由于<>中可以有多个范型,所以返回的是Type数组。这里需要注意的是,这个方法只会返回最外层<>里面的参数类型,嵌套的<>不会返回。
public final class Class<T> implements java.io.Serializable,
GenericDeclaration,
Type,
AnnotatedElement
Class继承了Type,所以最后可以直接强转为Class。