11/*
2- * Copyright 2009-2024 the original author or authors.
2+ * Copyright 2009-2025 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
2424import java .lang .reflect .TypeVariable ;
2525import java .lang .reflect .WildcardType ;
2626import java .util .Arrays ;
27+ import java .util .Objects ;
2728
2829/**
2930 * @author Iwao AVE!
31+ * @author Vladimir Sitnikov
3032 */
3133public class TypeParameterResolver {
3234
@@ -79,21 +81,26 @@ public static Type resolveReturnType(Method method, Type srcType) {
7981 public static Type [] resolveParamTypes (Method method , Type srcType ) {
8082 Type [] paramTypes = method .getGenericParameterTypes ();
8183 Class <?> declaringClass = method .getDeclaringClass ();
82- Type [] result = new Type [paramTypes .length ];
83- for (int i = 0 ; i < paramTypes .length ; i ++) {
84- result [i ] = resolveType (paramTypes [i ], srcType , declaringClass );
84+ return resolveTypes (paramTypes , srcType , declaringClass );
85+ }
86+
87+ private static Type [] resolveTypes (Type [] types , Type srcType , Class <?> declaringClass ) {
88+ Type [] args = new Type [types .length ];
89+ for (int i = 0 ; i < types .length ; i ++) {
90+ args [i ] = resolveType (types [i ], srcType , declaringClass );
8591 }
86- return result ;
92+ return args ;
8793 }
8894
8995 private static Type resolveType (Type type , Type srcType , Class <?> declaringClass ) {
9096 if (type instanceof TypeVariable ) {
9197 return resolveTypeVar ((TypeVariable <?>) type , srcType , declaringClass );
92- }
93- if (type instanceof ParameterizedType ) {
98+ } else if (type instanceof ParameterizedType ) {
9499 return resolveParameterizedType ((ParameterizedType ) type , srcType , declaringClass );
95100 } else if (type instanceof GenericArrayType ) {
96101 return resolveGenericArrayType ((GenericArrayType ) type , srcType , declaringClass );
102+ } else if (type instanceof WildcardType ) {
103+ return resolveWildcardType ((WildcardType ) type , srcType , declaringClass );
97104 } else {
98105 return type ;
99106 }
@@ -102,61 +109,28 @@ private static Type resolveType(Type type, Type srcType, Class<?> declaringClass
102109 private static Type resolveGenericArrayType (GenericArrayType genericArrayType , Type srcType ,
103110 Class <?> declaringClass ) {
104111 Type componentType = genericArrayType .getGenericComponentType ();
105- Type resolvedComponentType = null ;
106- if (componentType instanceof TypeVariable ) {
107- resolvedComponentType = resolveTypeVar ((TypeVariable <?>) componentType , srcType , declaringClass );
108- } else if (componentType instanceof GenericArrayType ) {
109- resolvedComponentType = resolveGenericArrayType ((GenericArrayType ) componentType , srcType , declaringClass );
110- } else if (componentType instanceof ParameterizedType ) {
111- resolvedComponentType = resolveParameterizedType ((ParameterizedType ) componentType , srcType , declaringClass );
112- }
112+ Type resolvedComponentType = resolveType (componentType , srcType , declaringClass );
113113 if (resolvedComponentType instanceof Class ) {
114114 return Array .newInstance ((Class <?>) resolvedComponentType , 0 ).getClass ();
115+ } else {
116+ return new GenericArrayTypeImpl (resolvedComponentType );
115117 }
116- return new GenericArrayTypeImpl (resolvedComponentType );
117118 }
118119
119120 private static ParameterizedType resolveParameterizedType (ParameterizedType parameterizedType , Type srcType ,
120121 Class <?> declaringClass ) {
121122 Class <?> rawType = (Class <?>) parameterizedType .getRawType ();
122123 Type [] typeArgs = parameterizedType .getActualTypeArguments ();
123- Type [] args = new Type [typeArgs .length ];
124- for (int i = 0 ; i < typeArgs .length ; i ++) {
125- if (typeArgs [i ] instanceof TypeVariable ) {
126- args [i ] = resolveTypeVar ((TypeVariable <?>) typeArgs [i ], srcType , declaringClass );
127- } else if (typeArgs [i ] instanceof ParameterizedType ) {
128- args [i ] = resolveParameterizedType ((ParameterizedType ) typeArgs [i ], srcType , declaringClass );
129- } else if (typeArgs [i ] instanceof WildcardType ) {
130- args [i ] = resolveWildcardType ((WildcardType ) typeArgs [i ], srcType , declaringClass );
131- } else {
132- args [i ] = typeArgs [i ];
133- }
134- }
124+ Type [] args = resolveTypes (typeArgs , srcType , declaringClass );
135125 return new ParameterizedTypeImpl (rawType , null , args );
136126 }
137127
138128 private static Type resolveWildcardType (WildcardType wildcardType , Type srcType , Class <?> declaringClass ) {
139- Type [] lowerBounds = resolveWildcardTypeBounds (wildcardType .getLowerBounds (), srcType , declaringClass );
140- Type [] upperBounds = resolveWildcardTypeBounds (wildcardType .getUpperBounds (), srcType , declaringClass );
129+ Type [] lowerBounds = resolveTypes (wildcardType .getLowerBounds (), srcType , declaringClass );
130+ Type [] upperBounds = resolveTypes (wildcardType .getUpperBounds (), srcType , declaringClass );
141131 return new WildcardTypeImpl (lowerBounds , upperBounds );
142132 }
143133
144- private static Type [] resolveWildcardTypeBounds (Type [] bounds , Type srcType , Class <?> declaringClass ) {
145- Type [] result = new Type [bounds .length ];
146- for (int i = 0 ; i < bounds .length ; i ++) {
147- if (bounds [i ] instanceof TypeVariable ) {
148- result [i ] = resolveTypeVar ((TypeVariable <?>) bounds [i ], srcType , declaringClass );
149- } else if (bounds [i ] instanceof ParameterizedType ) {
150- result [i ] = resolveParameterizedType ((ParameterizedType ) bounds [i ], srcType , declaringClass );
151- } else if (bounds [i ] instanceof WildcardType ) {
152- result [i ] = resolveWildcardType ((WildcardType ) bounds [i ], srcType , declaringClass );
153- } else {
154- result [i ] = bounds [i ];
155- }
156- }
157- return result ;
158- }
159-
160134 private static Type resolveTypeVar (TypeVariable <?> typeVar , Type srcType , Class <?> declaringClass ) {
161135 Type result ;
162136 Class <?> clazz ;
@@ -243,6 +217,7 @@ private static ParameterizedType translateParentTypeVars(ParameterizedType srcTy
243217 }
244218
245219 private TypeParameterResolver () {
220+ super ();
246221 }
247222
248223 static class ParameterizedTypeImpl implements ParameterizedType {
@@ -253,6 +228,7 @@ static class ParameterizedTypeImpl implements ParameterizedType {
253228 private final Type [] actualTypeArguments ;
254229
255230 public ParameterizedTypeImpl (Class <?> rawType , Type ownerType , Type [] actualTypeArguments ) {
231+ super ();
256232 this .rawType = rawType ;
257233 this .ownerType = ownerType ;
258234 this .actualTypeArguments = actualTypeArguments ;
@@ -273,6 +249,21 @@ public Type getRawType() {
273249 return rawType ;
274250 }
275251
252+ @ Override
253+ public int hashCode () {
254+ return (ownerType == null ? 0 : ownerType .hashCode ()) ^ Arrays .hashCode (actualTypeArguments ) ^ rawType .hashCode ();
255+ }
256+
257+ @ Override
258+ public boolean equals (Object obj ) {
259+ if (!(obj instanceof ParameterizedType )) {
260+ return false ;
261+ }
262+ ParameterizedType other = (ParameterizedType ) obj ;
263+ return rawType .equals (other .getRawType ()) && Objects .equals (ownerType , other .getOwnerType ())
264+ && Arrays .equals (actualTypeArguments , other .getActualTypeArguments ());
265+ }
266+
276267 @ Override
277268 public String toString () {
278269 return "ParameterizedTypeImpl [rawType=" + rawType + ", ownerType=" + ownerType + ", actualTypeArguments="
@@ -286,6 +277,7 @@ static class WildcardTypeImpl implements WildcardType {
286277 private final Type [] upperBounds ;
287278
288279 WildcardTypeImpl (Type [] lowerBounds , Type [] upperBounds ) {
280+ super ();
289281 this .lowerBounds = lowerBounds ;
290282 this .upperBounds = upperBounds ;
291283 }
@@ -299,18 +291,57 @@ public Type[] getLowerBounds() {
299291 public Type [] getUpperBounds () {
300292 return upperBounds ;
301293 }
294+
295+ @ Override
296+ public int hashCode () {
297+ final int prime = 31 ;
298+ int result = 1 ;
299+ result = prime * result + Arrays .hashCode (lowerBounds );
300+ result = prime * result + Arrays .hashCode (upperBounds );
301+ return result ;
302+ }
303+
304+ @ Override
305+ public boolean equals (Object obj ) {
306+ if (this == obj ) {
307+ return true ;
308+ }
309+ if (!(obj instanceof WildcardTypeImpl )) {
310+ return false ;
311+ }
312+ WildcardTypeImpl other = (WildcardTypeImpl ) obj ;
313+ return Arrays .equals (lowerBounds , other .lowerBounds ) && Arrays .equals (upperBounds , other .upperBounds );
314+ }
302315 }
303316
304317 static class GenericArrayTypeImpl implements GenericArrayType {
305318 private final Type genericComponentType ;
306319
307320 GenericArrayTypeImpl (Type genericComponentType ) {
321+ super ();
308322 this .genericComponentType = genericComponentType ;
309323 }
310324
311325 @ Override
312326 public Type getGenericComponentType () {
313327 return genericComponentType ;
314328 }
329+
330+ @ Override
331+ public int hashCode () {
332+ return Objects .hash (genericComponentType );
333+ }
334+
335+ @ Override
336+ public boolean equals (Object obj ) {
337+ if (this == obj ) {
338+ return true ;
339+ }
340+ if (!(obj instanceof GenericArrayTypeImpl )) {
341+ return false ;
342+ }
343+ GenericArrayTypeImpl other = (GenericArrayTypeImpl ) obj ;
344+ return Objects .equals (genericComponentType , other .genericComponentType );
345+ }
315346 }
316347}
0 commit comments