18
18
19
19
import java .lang .reflect .Array ;
20
20
import java .lang .reflect .GenericArrayType ;
21
+ import java .lang .reflect .MalformedParameterizedTypeException ;
21
22
import java .lang .reflect .Method ;
22
23
import java .lang .reflect .ParameterizedType ;
23
24
import java .lang .reflect .Type ;
@@ -74,12 +75,12 @@ public static Type getTargetType(MethodParameter methodParam) {
74
75
* @param clazz the class to resolve type variables against
75
76
* @return the corresponding generic parameter or return type
76
77
*/
77
- public static Class <?> resolveParameterType (MethodParameter methodParam , Class clazz ) {
78
+ public static Class <?> resolveParameterType (MethodParameter methodParam , Class <?> clazz ) {
78
79
Type genericType = getTargetType (methodParam );
79
80
Assert .notNull (clazz , "Class must not be null" );
80
81
Map <TypeVariable , Type > typeVariableMap = getTypeVariableMap (clazz );
81
82
Type rawType = getRawType (genericType , typeVariableMap );
82
- Class result = (rawType instanceof Class ? (Class ) rawType : methodParam .getParameterType ());
83
+ Class <?> result = (rawType instanceof Class ? (Class ) rawType : methodParam .getParameterType ());
83
84
methodParam .setParameterType (result );
84
85
methodParam .typeVariableMap = typeVariableMap ;
85
86
return result ;
@@ -227,7 +228,7 @@ public static Class<?> resolveReturnTypeArgument(Method method, Class<?> generic
227
228
* @param genericIfc the generic interface or superclass to resolve the type argument from
228
229
* @return the resolved type of the argument, or {@code null} if not resolvable
229
230
*/
230
- public static Class <?> resolveTypeArgument (Class clazz , Class genericIfc ) {
231
+ public static Class <?> resolveTypeArgument (Class <?> clazz , Class <?> genericIfc ) {
231
232
Class [] typeArgs = resolveTypeArguments (clazz , genericIfc );
232
233
if (typeArgs == null ) {
233
234
return null ;
@@ -248,11 +249,11 @@ public static Class<?> resolveTypeArgument(Class clazz, Class genericIfc) {
248
249
* @return the resolved type of each argument, with the array size matching the
249
250
* number of actual type arguments, or {@code null} if not resolvable
250
251
*/
251
- public static Class [] resolveTypeArguments (Class clazz , Class genericIfc ) {
252
+ public static Class [] resolveTypeArguments (Class <?> clazz , Class <?> genericIfc ) {
252
253
return doResolveTypeArguments (clazz , clazz , genericIfc );
253
254
}
254
255
255
- private static Class [] doResolveTypeArguments (Class ownerClass , Class classToIntrospect , Class genericIfc ) {
256
+ private static Class [] doResolveTypeArguments (Class <?> ownerClass , Class <?> classToIntrospect , Class <?> genericIfc ) {
256
257
while (classToIntrospect != null ) {
257
258
if (genericIfc .isInterface ()) {
258
259
Type [] ifcs = classToIntrospect .getGenericInterfaces ();
@@ -264,18 +265,23 @@ private static Class[] doResolveTypeArguments(Class ownerClass, Class classToInt
264
265
}
265
266
}
266
267
else {
267
- Class [] result = doResolveTypeArguments (
268
- ownerClass , classToIntrospect .getGenericSuperclass (), genericIfc );
269
- if (result != null ) {
270
- return result ;
268
+ try {
269
+ Class [] result = doResolveTypeArguments (ownerClass , classToIntrospect .getGenericSuperclass (), genericIfc );
270
+ if (result != null ) {
271
+ return result ;
272
+ }
273
+ }
274
+ catch (MalformedParameterizedTypeException ex ) {
275
+ // from getGenericSuperclass() - return null to skip further superclass traversal
276
+ return null ;
271
277
}
272
278
}
273
279
classToIntrospect = classToIntrospect .getSuperclass ();
274
280
}
275
281
return null ;
276
282
}
277
283
278
- private static Class [] doResolveTypeArguments (Class ownerClass , Type ifc , Class genericIfc ) {
284
+ private static Class [] doResolveTypeArguments (Class <?> ownerClass , Type ifc , Class <?> genericIfc ) {
279
285
if (ifc instanceof ParameterizedType ) {
280
286
ParameterizedType paramIfc = (ParameterizedType ) ifc ;
281
287
Type rawType = paramIfc .getRawType ();
@@ -301,7 +307,7 @@ else if (ifc != null && genericIfc.isAssignableFrom((Class) ifc)) {
301
307
/**
302
308
* Extract a class instance from given Type.
303
309
*/
304
- private static Class extractClass (Class ownerClass , Type arg ) {
310
+ private static Class <?> extractClass (Class <?> ownerClass , Type arg ) {
305
311
if (arg instanceof ParameterizedType ) {
306
312
return extractClass (ownerClass , ((ParameterizedType ) arg ).getRawType ());
307
313
}
@@ -368,7 +374,7 @@ static Type getRawType(Type genericType, Map<TypeVariable, Type> typeVariableMap
368
374
* {@link Class concrete classes} for the specified {@link Class}. Searches
369
375
* all super types, enclosing types and interfaces.
370
376
*/
371
- public static Map <TypeVariable , Type > getTypeVariableMap (Class clazz ) {
377
+ public static Map <TypeVariable , Type > getTypeVariableMap (Class <?> clazz ) {
372
378
Map <TypeVariable , Type > typeVariableMap = typeVariableCache .get (clazz );
373
379
374
380
if (typeVariableMap == null ) {
@@ -377,28 +383,37 @@ public static Map<TypeVariable, Type> getTypeVariableMap(Class clazz) {
377
383
// interfaces
378
384
extractTypeVariablesFromGenericInterfaces (clazz .getGenericInterfaces (), typeVariableMap );
379
385
380
- // super class
381
- Type genericType = clazz .getGenericSuperclass ();
382
- Class type = clazz .getSuperclass ();
383
- while (type != null && !Object .class .equals (type )) {
384
- if (genericType instanceof ParameterizedType ) {
385
- ParameterizedType pt = (ParameterizedType ) genericType ;
386
- populateTypeMapFromParameterizedType (pt , typeVariableMap );
386
+ try {
387
+ // super class
388
+ Class <?> type = clazz ;
389
+ while (type .getSuperclass () != null && !Object .class .equals (type .getSuperclass ())) {
390
+ Type genericType = type .getGenericSuperclass ();
391
+ if (genericType instanceof ParameterizedType ) {
392
+ ParameterizedType pt = (ParameterizedType ) genericType ;
393
+ populateTypeMapFromParameterizedType (pt , typeVariableMap );
394
+ }
395
+ extractTypeVariablesFromGenericInterfaces (type .getSuperclass ().getGenericInterfaces (), typeVariableMap );
396
+ type = type .getSuperclass ();
387
397
}
388
- extractTypeVariablesFromGenericInterfaces ( type . getGenericInterfaces (), typeVariableMap );
389
- genericType = type . getGenericSuperclass ();
390
- type = type . getSuperclass ();
398
+ }
399
+ catch ( MalformedParameterizedTypeException ex ) {
400
+ // from getGenericSuperclass() - ignore and continue with member class check
391
401
}
392
402
393
- // enclosing class
394
- type = clazz ;
395
- while (type .isMemberClass ()) {
396
- genericType = type .getGenericSuperclass ();
397
- if (genericType instanceof ParameterizedType ) {
398
- ParameterizedType pt = (ParameterizedType ) genericType ;
399
- populateTypeMapFromParameterizedType (pt , typeVariableMap );
403
+ try {
404
+ // enclosing class
405
+ Class <?> type = clazz ;
406
+ while (type .isMemberClass ()) {
407
+ Type genericType = type .getGenericSuperclass ();
408
+ if (genericType instanceof ParameterizedType ) {
409
+ ParameterizedType pt = (ParameterizedType ) genericType ;
410
+ populateTypeMapFromParameterizedType (pt , typeVariableMap );
411
+ }
412
+ type = type .getEnclosingClass ();
400
413
}
401
- type = type .getEnclosingClass ();
414
+ }
415
+ catch (MalformedParameterizedTypeException ex ) {
416
+ // from getGenericSuperclass() - ignore and preserve previously accumulated type variables
402
417
}
403
418
404
419
typeVariableCache .put (clazz , typeVariableMap );
0 commit comments