现象 1 2 3 4 5 6 Type  type  =  getClass().getGenericSuperclass();if  (type instanceof  ParameterizedType) {    ParameterizedType  parameterizedType  =  (ParameterizedType) type;     Class<R> requestClass = (Class<R>) parameterizedType.getActualTypeArguments()[0 ];     ... } 
第四行 Class<R> requestClass = (Class<R>) parameterizedType.getActualTypeArguments()[0] 报 java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class 错误
这个代码是子类想要拿到泛型参数时出现的类型转换异常
分析 上述问题中的类结构简化如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public  class  Request  {}public  class  Request2  extends  Request  {}public  class  Request3  extends  Request2  {}public  abstract  class  A <R extends  Request > {         public  void  requestHandle {         Type  type  =  getClass().getGenericSuperclass();         if  (type instanceof  ParameterizedType) {             ParameterizedType  parameterizedType  =  (ParameterizedType) type;             Class  requestClass  =  (Class) parameterizedType.getActualTypeArguments()[0 ];             ...         }     } } public  class  B <R extends  Request2 > extends  A <R> {} public  class  C  extends  B <Request3> {} 
1/ (new C).requestHandle(),所以 parameterizedType.getActualTypeArguments()[0] 拿到的其实就是 Request3.class  
2/ (new B).requestHandle()parameterizedType.getActualTypeArguments()[0] 返回的是 TypeVariable,不是 Class,这里很容易因为泛型的类型擦除误认为 parameterizedType.getActualTypeArguments()[0] 会返回 Request2.class 
解决 仔细观察 TypeVariable 接口定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public  interface  TypeVariable <D extends  GenericDeclaration > extends  Type , AnnotatedElement {         Type[] getBounds();          D getGenericDeclaration () ;          String getName () ;          AnnotatedType[] getAnnotatedBounds(); } 
我们可以调用 getBounds() 来获取泛型的上边界
最终调整如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public  void  requestHandle {    Type  type  =  getClass().getGenericSuperclass();     if  (type instanceof  ParameterizedType) {         ParameterizedType  parameterizedType  =  (ParameterizedType) type;         Type  actualTypeArgument  =  type.getActualTypeArguments()[0 ];                  if  (actualTypeArgument instanceof  Class) {             Class  requestClass  =  (Class) parameterizedType.getActualTypeArguments()[0 ];             ...         } else  if  (actualTypeArgument instanceof  TypeVariable) {             TypeVariable  v  =  (TypeVariable) actualTypeArgument;             Class  requestClass  =  (Class) v.getBounds()[0 ];             ...         }         ...     } }