@@ -96,12 +96,12 @@ public static Class<?> resolveParameterType(MethodParameter methodParam, Class c
96
96
97
97
/**
98
98
* Determine the target type for the generic return type of the given method,
99
- * where the type variable is declared on the given class.
99
+ * where formal type variables are declared on the given class.
100
100
*
101
101
* @param method the method to introspect
102
102
* @param clazz the class to resolve type variables against
103
103
* @return the corresponding generic parameter or return type
104
- * @see #resolveParameterizedReturnType
104
+ * @see #resolveReturnTypeForGenericMethod
105
105
*/
106
106
public static Class <?> resolveReturnType (Method method , Class <?> clazz ) {
107
107
Assert .notNull (method , "Method must not be null" );
@@ -114,27 +114,27 @@ public static Class<?> resolveReturnType(Method method, Class<?> clazz) {
114
114
115
115
/**
116
116
* Determine the target type for the generic return type of the given
117
- * <em>parameterized </em> method , where the type variable is declared
118
- * on the given method.
117
+ * <em>generic method </em>, where formal type variables are declared on
118
+ * the given method itself .
119
119
*
120
120
* <p>For example, given a factory method with the following signature,
121
- * if {@code resolveParameterizedReturnType ()} is invoked with the reflected
121
+ * if {@code resolveReturnTypeForGenericMethod ()} is invoked with the reflected
122
122
* method for {@code creatProxy()} and an {@code Object[]} array containing
123
- * {@code MyService.class}, {@code resolveParameterizedReturnType ()} will
123
+ * {@code MyService.class}, {@code resolveReturnTypeForGenericMethod ()} will
124
124
* infer that the target return type is {@code MyService}.
125
125
*
126
126
* <pre>{@code public static <T> T createProxy(Class<T> clazz)}</pre>
127
127
*
128
128
* <h4>Possible Return Values</h4>
129
129
* <ul>
130
- * <li>the target return type if it can be inferred</li>
131
- * <li>the {@link Method#getReturnType() standard return type}, if
132
- * the given {@code method} does not declare any {@link
133
- * Method#getTypeParameters() generic types }</li>
134
- * <li>the {@link Method#getReturnType() standard return type}, if the
130
+ * <li>the target return type, if it can be inferred</li>
131
+ * <li>the {@linkplain Method#getReturnType() standard return type}, if
132
+ * the given {@code method} does not declare any {@linkplain
133
+ * Method#getTypeParameters() formal type variables }</li>
134
+ * <li>the {@linkplain Method#getReturnType() standard return type}, if the
135
135
* target return type cannot be inferred (e.g., due to type erasure)</li>
136
136
* <li>{@code null}, if the length of the given arguments array is shorter
137
- * than the length of the {@link
137
+ * than the length of the {@linkplain
138
138
* Method#getGenericParameterTypes() formal argument list} for the given
139
139
* method</li>
140
140
* </ul>
@@ -147,60 +147,59 @@ public static Class<?> resolveReturnType(Method method, Class<?> clazz) {
147
147
* @since 3.2
148
148
* @see #resolveReturnType
149
149
*/
150
- public static Class <?> resolveParameterizedReturnType (Method method , Object [] args ) {
150
+ public static Class <?> resolveReturnTypeForGenericMethod (Method method , Object [] args ) {
151
151
Assert .notNull (method , "method must not be null" );
152
152
Assert .notNull (args , "args must not be null" );
153
153
154
- final TypeVariable <Method >[] declaredGenericTypes = method .getTypeParameters ();
155
- final Type genericReturnType = method .getGenericReturnType ();
156
- final Type [] genericArgumentTypes = method .getGenericParameterTypes ();
157
-
158
154
if (logger .isDebugEnabled ()) {
159
- logger .debug (String .format (
160
- "Resolving parameterized return type for [%s] with concrete method arguments [%s]." ,
155
+ logger .debug (String .format ("Resolving return type for [%s] with concrete method arguments [%s]." ,
161
156
method .toGenericString (), ObjectUtils .nullSafeToString (args )));
162
157
}
163
158
164
- // No declared generic types to inspect, so just return the standard return type.
165
- if (declaredGenericTypes .length == 0 ) {
159
+ final TypeVariable <Method >[] declaredTypeVariables = method .getTypeParameters ();
160
+ final Type genericReturnType = method .getGenericReturnType ();
161
+ final Type [] methodArgumentTypes = method .getGenericParameterTypes ();
162
+
163
+ // No declared type variables to inspect, so just return the standard return type.
164
+ if (declaredTypeVariables .length == 0 ) {
166
165
return method .getReturnType ();
167
166
}
168
167
169
168
// The supplied argument list is too short for the method's signature, so
170
169
// return null, since such a method invocation would fail.
171
- if (args .length < genericArgumentTypes .length ) {
170
+ if (args .length < methodArgumentTypes .length ) {
172
171
return null ;
173
172
}
174
173
175
- // Ensure that the generic type is declared directly on the method
176
- // itself, not on the enclosing class or interface.
177
- boolean locallyDeclaredGenericTypeMatchesReturnType = false ;
178
- for (TypeVariable <Method > currentType : declaredGenericTypes ) {
179
- if (currentType .equals (genericReturnType )) {
174
+ // Ensure that the type variable (e.g., T) is declared directly on the method
175
+ // itself (e.g., via <T>) , not on the enclosing class or interface.
176
+ boolean locallyDeclaredTypeVariableMatchesReturnType = false ;
177
+ for (TypeVariable <Method > currentTypeVariable : declaredTypeVariables ) {
178
+ if (currentTypeVariable .equals (genericReturnType )) {
180
179
if (logger .isDebugEnabled ()) {
181
180
logger .debug (String .format (
182
- "Found declared generic type [%s] that matches the target return type [%s]." ,
183
- currentType , genericReturnType ));
181
+ "Found declared type variable [%s] that matches the target return type [%s]." ,
182
+ currentTypeVariable , genericReturnType ));
184
183
}
185
- locallyDeclaredGenericTypeMatchesReturnType = true ;
184
+ locallyDeclaredTypeVariableMatchesReturnType = true ;
186
185
break ;
187
186
}
188
187
}
189
188
190
- if (locallyDeclaredGenericTypeMatchesReturnType ) {
191
- for (int i = 0 ; i < genericArgumentTypes .length ; i ++) {
192
- final Type currentArgumentType = genericArgumentTypes [i ];
189
+ if (locallyDeclaredTypeVariableMatchesReturnType ) {
190
+ for (int i = 0 ; i < methodArgumentTypes .length ; i ++) {
191
+ final Type currentMethodArgumentType = methodArgumentTypes [i ];
193
192
194
- if (currentArgumentType .equals (genericReturnType )) {
193
+ if (currentMethodArgumentType .equals (genericReturnType )) {
195
194
if (logger .isDebugEnabled ()) {
196
195
logger .debug (String .format (
197
- "Found generic method argument at index [%s] that matches the target return type." , i ));
196
+ "Found method argument type at index [%s] that matches the target return type." , i ));
198
197
}
199
198
return args [i ].getClass ();
200
199
}
201
200
202
- if (currentArgumentType instanceof ParameterizedType ) {
203
- ParameterizedType parameterizedType = (ParameterizedType ) currentArgumentType ;
201
+ if (currentMethodArgumentType instanceof ParameterizedType ) {
202
+ ParameterizedType parameterizedType = (ParameterizedType ) currentMethodArgumentType ;
204
203
Type [] actualTypeArguments = parameterizedType .getActualTypeArguments ();
205
204
206
205
for (int j = 0 ; j < actualTypeArguments .length ; j ++) {
@@ -209,7 +208,7 @@ public static Class<?> resolveParameterizedReturnType(Method method, Object[] ar
209
208
if (typeArg .equals (genericReturnType )) {
210
209
if (logger .isDebugEnabled ()) {
211
210
logger .debug (String .format (
212
- "Found method argument at index [%s] that is parameterized with a type that matches the target return type." ,
211
+ "Found method argument type at index [%s] that is parameterized with a type argument that matches the target return type." ,
213
212
i ));
214
213
}
215
214
@@ -219,7 +218,7 @@ public static Class<?> resolveParameterizedReturnType(Method method, Object[] ar
219
218
// Consider adding logic to determine the class of the
220
219
// J'th typeArg, if possible.
221
220
logger .info (String .format (
222
- "Could not determine the target type for parameterized type [%s] for method [%s]." ,
221
+ "Could not determine the target type for type argument [%s] for method [%s]." ,
223
222
typeArg , method .toGenericString ()));
224
223
225
224
// For now, just fall back...
0 commit comments