View Javadoc
1   /*
2    * Copyright 2002-2015 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.core;
18  
19  import java.io.ObjectStreamException;
20  import java.io.Serializable;
21  import java.lang.reflect.Array;
22  import java.lang.reflect.Constructor;
23  import java.lang.reflect.Field;
24  import java.lang.reflect.GenericArrayType;
25  import java.lang.reflect.Method;
26  import java.lang.reflect.ParameterizedType;
27  import java.lang.reflect.Type;
28  import java.lang.reflect.TypeVariable;
29  import java.lang.reflect.WildcardType;
30  import java.util.Collection;
31  import java.util.IdentityHashMap;
32  import java.util.Map;
33  
34  import org.springframework.core.SerializableTypeWrapper.FieldTypeProvider;
35  import org.springframework.core.SerializableTypeWrapper.MethodParameterTypeProvider;
36  import org.springframework.core.SerializableTypeWrapper.TypeProvider;
37  import org.springframework.util.Assert;
38  import org.springframework.util.ClassUtils;
39  import org.springframework.util.ConcurrentReferenceHashMap;
40  import org.springframework.util.ObjectUtils;
41  import org.springframework.util.StringUtils;
42  
43  /**
44   * Encapsulates a Java {@link java.lang.reflect.Type}, providing access to
45   * {@link #getSuperType() supertypes}, {@link #getInterfaces() interfaces}, and
46   * {@link #getGeneric(int...) generic parameters} along with the ability to ultimately
47   * {@link #resolve() resolve} to a {@link java.lang.Class}.
48   *
49   * <p>{@code ResolvableTypes} may be obtained from {@link #forField(Field) fields},
50   * {@link #forMethodParameter(Method, int) method parameters},
51   * {@link #forMethodReturnType(Method) method returns} or
52   * {@link #forClass(Class) classes}. Most methods on this class will themselves return
53   * {@link ResolvableType}s, allowing easy navigation. For example:
54   * <pre class="code">
55   * private HashMap&lt;Integer, List&lt;String&gt;&gt; myMap;
56   *
57   * public void example() {
58   *     ResolvableType t = ResolvableType.forField(getClass().getDeclaredField("myMap"));
59   *     t.getSuperType(); // AbstractMap&lt;Integer, List&lt;String&gt;&gt;
60   *     t.asMap(); // Map&lt;Integer, List&lt;String&gt;&gt;
61   *     t.getGeneric(0).resolve(); // Integer
62   *     t.getGeneric(1).resolve(); // List
63   *     t.getGeneric(1); // List&lt;String&gt;
64   *     t.resolveGeneric(1, 0); // String
65   * }
66   * </pre>
67   *
68   * @author Phillip Webb
69   * @author Juergen Hoeller
70   * @since 4.0
71   * @see #forField(Field)
72   * @see #forMethodParameter(Method, int)
73   * @see #forMethodReturnType(Method)
74   * @see #forConstructorParameter(Constructor, int)
75   * @see #forClass(Class)
76   * @see #forType(Type)
77   */
78  @SuppressWarnings("serial")
79  public final class ResolvableType implements Serializable {
80  
81  	/**
82  	 * {@code ResolvableType} returned when no value is available. {@code NONE} is used
83  	 * in preference to {@code null} so that multiple method calls can be safely chained.
84  	 */
85  	public static final ResolvableType NONE = new ResolvableType(null, null, null, null);
86  
87  	private static final ResolvableType[] EMPTY_TYPES_ARRAY = new ResolvableType[0];
88  
89  	private static final ConcurrentReferenceHashMap<ResolvableType, ResolvableType> cache =
90  			new ConcurrentReferenceHashMap<ResolvableType, ResolvableType>(256);
91  
92  
93  	/**
94  	 * The underlying Java type being managed (only ever {@code null} for {@link #NONE}).
95  	 */
96  	private final Type type;
97  
98  	/**
99  	 * Optional provider for the type.
100 	 */
101 	private final TypeProvider typeProvider;
102 
103 	/**
104 	 * The {@code VariableResolver} to use or {@code null} if no resolver is available.
105 	 */
106 	private final VariableResolver variableResolver;
107 
108 	/**
109 	 * The component type for an array or {@code null} if the type should be deduced.
110 	 */
111 	private final ResolvableType componentType;
112 
113 	/**
114 	 * Copy of the resolved value.
115 	 */
116 	private final Class<?> resolved;
117 
118 	private ResolvableType superType;
119 
120 	private ResolvableType[] interfaces;
121 
122 	private ResolvableType[] generics;
123 
124 
125 	/**
126 	 * Private constructor used to create a new {@link ResolvableType} for cache key purposes.
127 	 */
128 	private ResolvableType(Type type, TypeProvider typeProvider, VariableResolver variableResolver) {
129 		this.type = type;
130 		this.typeProvider = typeProvider;
131 		this.variableResolver = variableResolver;
132 		this.componentType = null;
133 		this.resolved = null;
134 	}
135 
136 	/**
137 	 * Private constructor used to create a new {@link ResolvableType} for resolution purposes.
138 	 */
139 	private ResolvableType(
140 			Type type, TypeProvider typeProvider, VariableResolver variableResolver, ResolvableType componentType) {
141 
142 		this.type = type;
143 		this.typeProvider = typeProvider;
144 		this.variableResolver = variableResolver;
145 		this.componentType = componentType;
146 		this.resolved = resolveClass();
147 	}
148 
149 
150 	/**
151 	 * Return the underling Java {@link Type} being managed. With the exception of
152 	 * the {@link #NONE} constant, this method will never return {@code null}.
153 	 */
154 	public Type getType() {
155 		return SerializableTypeWrapper.unwrap(this.type);
156 	}
157 
158 	/**
159 	 * Return the underlying Java {@link Class} being managed, if available;
160 	 * otherwise {@code null}.
161 	 */
162 	public Class<?> getRawClass() {
163 		Type rawType = this.type;
164 		if (rawType instanceof ParameterizedType) {
165 			rawType = ((ParameterizedType) rawType).getRawType();
166 		}
167 		return (rawType instanceof Class ? (Class<?>) rawType : null);
168 	}
169 
170 	/**
171 	 * Return the underlying source of the resolvable type. Will return a {@link Field},
172 	 * {@link MethodParameter} or {@link Type} depending on how the {@link ResolvableType}
173 	 * was constructed. With the exception of the {@link #NONE} constant, this method will
174 	 * never return {@code null}. This method is primarily to provide access to additional
175 	 * type information or meta-data that alternative JVM languages may provide.
176 	 */
177 	public Object getSource() {
178 		Object source = (this.typeProvider != null ? this.typeProvider.getSource() : null);
179 		return (source != null ? source : this.type);
180 	}
181 
182 	/**
183 	 * Determine whether this {@code ResolvableType} is assignable from the
184 	 * specified other type.
185 	 * <p>Attempts to follow the same rules as the Java compiler, considering
186 	 * whether both the {@link #resolve() resolved} {@code Class} is
187 	 * {@link Class#isAssignableFrom(Class) assignable from} the given type
188 	 * as well as whether all {@link #getGenerics() generics} are assignable.
189 	 * @param other the type to be checked against
190 	 * @return {@code true} if the specified other type can be assigned to this
191 	 * {@code ResolvableType}; {@code false} otherwise
192 	 */
193 	public boolean isAssignableFrom(ResolvableType other) {
194 		return isAssignableFrom(other, null);
195 	}
196 
197 	private boolean isAssignableFrom(ResolvableType other, Map<Type, Type> matchedBefore) {
198 		Assert.notNull(other, "ResolvableType must not be null");
199 
200 		// If we cannot resolve types, we are not assignable
201 		if (this == NONE || other == NONE) {
202 			return false;
203 		}
204 
205 		// Deal with array by delegating to the component type
206 		if (isArray()) {
207 			return (other.isArray() && getComponentType().isAssignableFrom(other.getComponentType()));
208 		}
209 
210 		if (matchedBefore != null && matchedBefore.get(this.type) == other.type) {
211 			return true;
212 		}
213 
214 		// Deal with wildcard bounds
215 		WildcardBounds ourBounds = WildcardBounds.get(this);
216 		WildcardBounds typeBounds = WildcardBounds.get(other);
217 
218 		// In the from X is assignable to <? extends Number>
219 		if (typeBounds != null) {
220 			return (ourBounds != null && ourBounds.isSameKind(typeBounds) &&
221 					ourBounds.isAssignableFrom(typeBounds.getBounds()));
222 		}
223 
224 		// In the form <? extends Number> is assignable to X...
225 		if (ourBounds != null) {
226 			return ourBounds.isAssignableFrom(other);
227 		}
228 
229 		// Main assignability check about to follow
230 		boolean exactMatch = (matchedBefore != null);  // We're checking nested generic variables now...
231 		boolean checkGenerics = true;
232 		Class<?> ourResolved = null;
233 		if (this.type instanceof TypeVariable) {
234 			TypeVariable<?> variable = (TypeVariable<?>) this.type;
235 			// Try default variable resolution
236 			if (this.variableResolver != null) {
237 				ResolvableType resolved = this.variableResolver.resolveVariable(variable);
238 				if (resolved != null) {
239 					ourResolved = resolved.resolve();
240 				}
241 			}
242 			if (ourResolved == null) {
243 				// Try variable resolution against target type
244 				if (other.variableResolver != null) {
245 					ResolvableType resolved = other.variableResolver.resolveVariable(variable);
246 					if (resolved != null) {
247 						ourResolved = resolved.resolve();
248 						checkGenerics = false;
249 					}
250 				}
251 			}
252 			if (ourResolved == null) {
253 				// Unresolved type variable, potentially nested -> never insist on exact match
254 				exactMatch = false;
255 			}
256 		}
257 		if (ourResolved == null) {
258 			ourResolved = resolve(Object.class);
259 		}
260 		Class<?> otherResolved = other.resolve(Object.class);
261 
262 		// We need an exact type match for generics
263 		// List<CharSequence> is not assignable from List<String>
264 		if (exactMatch ? !ourResolved.equals(otherResolved) : !ClassUtils.isAssignable(ourResolved, otherResolved)) {
265 			return false;
266 		}
267 
268 		if (checkGenerics) {
269 			// Recursively check each generic
270 			ResolvableType[] ourGenerics = getGenerics();
271 			ResolvableType[] typeGenerics = other.as(ourResolved).getGenerics();
272 			if (ourGenerics.length != typeGenerics.length) {
273 				return false;
274 			}
275 			if (matchedBefore == null) {
276 				matchedBefore = new IdentityHashMap<Type, Type>(1);
277 			}
278 			matchedBefore.put(this.type, other.type);
279 			for (int i = 0; i < ourGenerics.length; i++) {
280 				if (!ourGenerics[i].isAssignableFrom(typeGenerics[i], matchedBefore)) {
281 					return false;
282 				}
283 			}
284 		}
285 
286 		return true;
287 	}
288 
289 	/**
290 	 * Return {@code true} if this type resolves to a Class that represents an array.
291 	 * @see #getComponentType()
292 	 */
293 	public boolean isArray() {
294 		if (this == NONE) {
295 			return false;
296 		}
297 		return (((this.type instanceof Class && ((Class<?>) this.type).isArray())) ||
298 				this.type instanceof GenericArrayType || resolveType().isArray());
299 	}
300 
301 	/**
302 	 * Return the ResolvableType representing the component type of the array or
303 	 * {@link #NONE} if this type does not represent an array.
304 	 * @see #isArray()
305 	 */
306 	public ResolvableType getComponentType() {
307 		if (this == NONE) {
308 			return NONE;
309 		}
310 		if (this.componentType != null) {
311 			return this.componentType;
312 		}
313 		if (this.type instanceof Class) {
314 			Class<?> componentType = ((Class<?>) this.type).getComponentType();
315 			return forType(componentType, this.variableResolver);
316 		}
317 		if (this.type instanceof GenericArrayType) {
318 			return forType(((GenericArrayType) this.type).getGenericComponentType(), this.variableResolver);
319 		}
320 		return resolveType().getComponentType();
321 	}
322 
323 	/**
324 	 * Convenience method to return this type as a resolvable {@link Collection} type.
325 	 * Returns {@link #NONE} if this type does not implement or extend
326 	 * {@link Collection}.
327 	 * @see #as(Class)
328 	 * @see #asMap()
329 	 */
330 	public ResolvableType asCollection() {
331 		return as(Collection.class);
332 	}
333 
334 	/**
335 	 * Convenience method to return this type as a resolvable {@link Map} type.
336 	 * Returns {@link #NONE} if this type does not implement or extend
337 	 * {@link Map}.
338 	 * @see #as(Class)
339 	 * @see #asCollection()
340 	 */
341 	public ResolvableType asMap() {
342 		return as(Map.class);
343 	}
344 
345 	/**
346 	 * Return this type as a {@link ResolvableType} of the specified class. Searches
347 	 * {@link #getSuperType() supertype} and {@link #getInterfaces() interface}
348 	 * hierarchies to find a match, returning {@link #NONE} if this type does not
349 	 * implement or extend the specified class.
350 	 * @param type the required class type
351 	 * @return a {@link ResolvableType} representing this object as the specified
352 	 * type or {@link #NONE}
353 	 * @see #asCollection()
354 	 * @see #asMap()
355 	 * @see #getSuperType()
356 	 * @see #getInterfaces()
357 	 */
358 	public ResolvableType as(Class<?> type) {
359 		if (this == NONE) {
360 			return NONE;
361 		}
362 		if (ObjectUtils.nullSafeEquals(resolve(), type)) {
363 			return this;
364 		}
365 		for (ResolvableType interfaceType : getInterfaces()) {
366 			ResolvableType interfaceAsType = interfaceType.as(type);
367 			if (interfaceAsType != NONE) {
368 				return interfaceAsType;
369 			}
370 		}
371 		return getSuperType().as(type);
372 	}
373 
374 	/**
375 	 * Return a {@link ResolvableType} representing the direct supertype of this type.
376 	 * If no supertype is available this method returns {@link #NONE}.
377 	 * @see #getInterfaces()
378 	 */
379 	public ResolvableType getSuperType() {
380 		Class<?> resolved = resolve();
381 		if (resolved == null || resolved.getGenericSuperclass() == null) {
382 			return NONE;
383 		}
384 		if (this.superType == null) {
385 			this.superType = forType(SerializableTypeWrapper.forGenericSuperclass(resolved),
386 					asVariableResolver());
387 		}
388 		return this.superType;
389 	}
390 
391 	/**
392 	 * Return a {@link ResolvableType} array representing the direct interfaces
393 	 * implemented by this type. If this type does not implement any interfaces an
394 	 * empty array is returned.
395 	 * @see #getSuperType()
396 	 */
397 	public ResolvableType[] getInterfaces() {
398 		Class<?> resolved = resolve();
399 		if (resolved == null || ObjectUtils.isEmpty(resolved.getGenericInterfaces())) {
400 			return EMPTY_TYPES_ARRAY;
401 		}
402 		if (this.interfaces == null) {
403 			this.interfaces = forTypes(SerializableTypeWrapper.forGenericInterfaces(resolved),
404 					asVariableResolver());
405 		}
406 		return this.interfaces;
407 	}
408 
409 	/**
410 	 * Return {@code true} if this type contains generic parameters.
411 	 * @see #getGeneric(int...)
412 	 * @see #getGenerics()
413 	 */
414 	public boolean hasGenerics() {
415 		return (getGenerics().length > 0);
416 	}
417 
418 	/**
419 	 * Return {@code true} if this type contains unresolvable generics only,
420 	 * that is, no substitute for any of its declared type variables.
421 	 */
422 	boolean isEntirelyUnresolvable() {
423 		if (this == NONE) {
424 			return false;
425 		}
426 		ResolvableType[] generics = getGenerics();
427 		for (ResolvableType generic : generics) {
428 			if (!generic.isUnresolvableTypeVariable() && !generic.isWildcardWithoutBounds()) {
429 				return false;
430 			}
431 		}
432 		return true;
433 	}
434 
435 	/**
436 	 * Determine whether the underlying type has any unresolvable generics:
437 	 * either through an unresolvable type variable on the type itself
438 	 * or through implementing a generic interface in a raw fashion,
439 	 * i.e. without substituting that interface's type variables.
440 	 * The result will be {@code true} only in those two scenarios.
441 	 */
442 	public boolean hasUnresolvableGenerics() {
443 		if (this == NONE) {
444 			return false;
445 		}
446 		ResolvableType[] generics = getGenerics();
447 		for (ResolvableType generic : generics) {
448 			if (generic.isUnresolvableTypeVariable() || generic.isWildcardWithoutBounds()) {
449 				return true;
450 			}
451 		}
452 		Class<?> resolved = resolve();
453 		if (resolved != null) {
454 			for (Type genericInterface : resolved.getGenericInterfaces()) {
455 				if (genericInterface instanceof Class) {
456 					if (forClass((Class<?>) genericInterface).hasGenerics()) {
457 						return true;
458 					}
459 				}
460 			}
461 			return getSuperType().hasUnresolvableGenerics();
462 		}
463 		return false;
464 	}
465 
466 	/**
467 	 * Determine whether the underlying type is a type variable that
468 	 * cannot be resolved through the associated variable resolver.
469 	 */
470 	private boolean isUnresolvableTypeVariable() {
471 		if (this.type instanceof TypeVariable) {
472 			if (this.variableResolver == null) {
473 				return true;
474 			}
475 			TypeVariable<?> variable = (TypeVariable<?>) this.type;
476 			ResolvableType resolved = this.variableResolver.resolveVariable(variable);
477 			if (resolved == null || resolved.isUnresolvableTypeVariable()) {
478 				return true;
479 			}
480 		}
481 		return false;
482 	}
483 
484 	/**
485 	 * Determine whether the underlying type represents a wildcard
486 	 * without specific bounds (i.e., equal to {@code ? extends Object}).
487 	 */
488 	private boolean isWildcardWithoutBounds() {
489 		if (this.type instanceof WildcardType) {
490 			WildcardType wt = (WildcardType) this.type;
491 			if (wt.getLowerBounds().length == 0) {
492 				Type[] upperBounds = wt.getUpperBounds();
493 				if (upperBounds.length == 0 || (upperBounds.length == 1 && Object.class.equals(upperBounds[0]))) {
494 					return true;
495 				}
496 			}
497 		}
498 		return false;
499 	}
500 
501 	/**
502 	 * Return a {@link ResolvableType} for the specified nesting level. See
503 	 * {@link #getNested(int, Map)} for details.
504 	 * @param nestingLevel the nesting level
505 	 * @return the {@link ResolvableType} type, or {@code #NONE}
506 	 */
507 	public ResolvableType getNested(int nestingLevel) {
508 		return getNested(nestingLevel, null);
509 	}
510 
511 	/**
512 	 * Return a {@link ResolvableType} for the specified nesting level. The nesting level
513 	 * refers to the specific generic parameter that should be returned. A nesting level
514 	 * of 1 indicates this type; 2 indicates the first nested generic; 3 the second; and so
515 	 * on. For example, given {@code List<Set<Integer>>} level 1 refers to the
516 	 * {@code List}, level 2 the {@code Set}, and level 3 the {@code Integer}.
517 	 * <p>The {@code typeIndexesPerLevel} map can be used to reference a specific generic
518 	 * for the given level. For example, an index of 0 would refer to a {@code Map} key;
519 	 * whereas, 1 would refer to the value. If the map does not contain a value for a
520 	 * specific level the last generic will be used (e.g. a {@code Map} value).
521 	 * <p>Nesting levels may also apply to array types; for example given
522 	 * {@code String[]}, a nesting level of 2 refers to {@code String}.
523 	 * <p>If a type does not {@link #hasGenerics() contain} generics the
524 	 * {@link #getSuperType() supertype} hierarchy will be considered.
525 	 * @param nestingLevel the required nesting level, indexed from 1 for the current
526 	 * type, 2 for the first nested generic, 3 for the second and so on
527 	 * @param typeIndexesPerLevel a map containing the generic index for a given nesting
528 	 * level (may be {@code null})
529 	 * @return a {@link ResolvableType} for the nested level or {@link #NONE}
530 	 */
531 	public ResolvableType getNested(int nestingLevel, Map<Integer, Integer> typeIndexesPerLevel) {
532 		ResolvableType result = this;
533 		for (int i = 2; i <= nestingLevel; i++) {
534 			if (result.isArray()) {
535 				result = result.getComponentType();
536 			}
537 			else {
538 				// Handle derived types
539 				while (result != ResolvableType.NONE && !result.hasGenerics()) {
540 					result = result.getSuperType();
541 				}
542 				Integer index = (typeIndexesPerLevel != null ? typeIndexesPerLevel.get(i) : null);
543 				index = (index == null ? result.getGenerics().length - 1 : index);
544 				result = result.getGeneric(index);
545 			}
546 		}
547 		return result;
548 	}
549 
550 	/**
551 	 * Return a {@link ResolvableType} representing the generic parameter for the given
552 	 * indexes. Indexes are zero based; for example given the type
553 	 * {@code Map<Integer, List<String>>}, {@code getGeneric(0)} will access the
554 	 * {@code Integer}. Nested generics can be accessed by specifying multiple indexes;
555 	 * for example {@code getGeneric(1, 0)} will access the {@code String} from the nested
556 	 * {@code List}. For convenience, if no indexes are specified the first generic is
557 	 * returned.
558 	 * <p>If no generic is available at the specified indexes {@link #NONE} is returned.
559 	 * @param indexes the indexes that refer to the generic parameter (may be omitted to
560 	 * return the first generic)
561 	 * @return a {@link ResolvableType} for the specified generic or {@link #NONE}
562 	 * @see #hasGenerics()
563 	 * @see #getGenerics()
564 	 * @see #resolveGeneric(int...)
565 	 * @see #resolveGenerics()
566 	 */
567 	public ResolvableType getGeneric(int... indexes) {
568 		try {
569 			if (indexes == null || indexes.length == 0) {
570 				return getGenerics()[0];
571 			}
572 			ResolvableType generic = this;
573 			for (int index : indexes) {
574 				generic = generic.getGenerics()[index];
575 			}
576 			return generic;
577 		}
578 		catch (IndexOutOfBoundsException ex) {
579 			return NONE;
580 		}
581 	}
582 
583 	/**
584 	 * Return an array of {@link ResolvableType}s representing the generic parameters of
585 	 * this type. If no generics are available an empty array is returned. If you need to
586 	 * access a specific generic consider using the {@link #getGeneric(int...)} method as
587 	 * it allows access to nested generics and protects against
588 	 * {@code IndexOutOfBoundsExceptions}.
589 	 * @return an array of {@link ResolvableType}s representing the generic parameters
590 	 * (never {@code null})
591 	 * @see #hasGenerics()
592 	 * @see #getGeneric(int...)
593 	 * @see #resolveGeneric(int...)
594 	 * @see #resolveGenerics()
595 	 */
596 	public ResolvableType[] getGenerics() {
597 		if (this == NONE) {
598 			return EMPTY_TYPES_ARRAY;
599 		}
600 		if (this.generics == null) {
601 			if (this.type instanceof Class) {
602 				Class<?> typeClass = (Class<?>) this.type;
603 				this.generics = forTypes(SerializableTypeWrapper.forTypeParameters(typeClass), this.variableResolver);
604 			}
605 			else if (this.type instanceof ParameterizedType) {
606 				Type[] actualTypeArguments = ((ParameterizedType) this.type).getActualTypeArguments();
607 				ResolvableType[] generics = new ResolvableType[actualTypeArguments.length];
608 				for (int i = 0; i < actualTypeArguments.length; i++) {
609 					generics[i] = forType(actualTypeArguments[i], this.variableResolver);
610 				}
611 				this.generics = generics;
612 			}
613 			else {
614 				this.generics = resolveType().getGenerics();
615 			}
616 		}
617 		return this.generics;
618 	}
619 
620 	/**
621 	 * Convenience method that will {@link #getGenerics() get} and
622 	 * {@link #resolve() resolve} generic parameters.
623 	 * @return an array of resolved generic parameters (the resulting array
624 	 * will never be {@code null}, but it may contain {@code null} elements})
625 	 * @see #getGenerics()
626 	 * @see #resolve()
627 	 */
628 	public Class<?>[] resolveGenerics() {
629 		return resolveGenerics(null);
630 	}
631 
632 	/**
633 	 * Convenience method that will {@link #getGenerics() get} and {@link #resolve()
634 	 * resolve} generic parameters, using the specified {@code fallback} if any type
635 	 * cannot be resolved.
636 	 * @param fallback the fallback class to use if resolution fails (may be {@code null})
637 	 * @return an array of resolved generic parameters (the resulting array will never be
638 	 * {@code null}, but it may contain {@code null} elements})
639 	 * @see #getGenerics()
640 	 * @see #resolve()
641 	 */
642 	public Class<?>[] resolveGenerics(Class<?> fallback) {
643 		ResolvableType[] generics = getGenerics();
644 		Class<?>[] resolvedGenerics = new Class<?>[generics.length];
645 		for (int i = 0; i < generics.length; i++) {
646 			resolvedGenerics[i] = generics[i].resolve(fallback);
647 		}
648 		return resolvedGenerics;
649 	}
650 
651 	/**
652 	 * Convenience method that will {@link #getGeneric(int...) get} and
653 	 * {@link #resolve() resolve} a specific generic parameters.
654 	 * @param indexes the indexes that refer to the generic parameter
655 	 * (may be omitted to return the first generic)
656 	 * @return a resolved {@link Class} or {@code null}
657 	 * @see #getGeneric(int...)
658 	 * @see #resolve()
659 	 */
660 	public Class<?> resolveGeneric(int... indexes) {
661 		return getGeneric(indexes).resolve();
662 	}
663 
664 	/**
665 	 * Resolve this type to a {@link java.lang.Class}, returning {@code null}
666 	 * if the type cannot be resolved. This method will consider bounds of
667 	 * {@link TypeVariable}s and {@link WildcardType}s if direct resolution fails;
668 	 * however, bounds of {@code Object.class} will be ignored.
669 	 * @return the resolved {@link Class}, or {@code null} if not resolvable
670 	 * @see #resolve(Class)
671 	 * @see #resolveGeneric(int...)
672 	 * @see #resolveGenerics()
673 	 */
674 	public Class<?> resolve() {
675 		return resolve(null);
676 	}
677 
678 	/**
679 	 * Resolve this type to a {@link java.lang.Class}, returning the specified
680 	 * {@code fallback} if the type cannot be resolved. This method will consider bounds
681 	 * of {@link TypeVariable}s and {@link WildcardType}s if direct resolution fails;
682 	 * however, bounds of {@code Object.class} will be ignored.
683 	 * @param fallback the fallback class to use if resolution fails (may be {@code null})
684 	 * @return the resolved {@link Class} or the {@code fallback}
685 	 * @see #resolve()
686 	 * @see #resolveGeneric(int...)
687 	 * @see #resolveGenerics()
688 	 */
689 	public Class<?> resolve(Class<?> fallback) {
690 		return (this.resolved != null ? this.resolved : fallback);
691 	}
692 
693 	private Class<?> resolveClass() {
694 		if (this.type instanceof Class || this.type == null) {
695 			return (Class<?>) this.type;
696 		}
697 		if (this.type instanceof GenericArrayType) {
698 			Class<?> resolvedComponent = getComponentType().resolve();
699 			return (resolvedComponent != null ? Array.newInstance(resolvedComponent, 0).getClass() : null);
700 		}
701 		return resolveType().resolve();
702 	}
703 
704 	/**
705 	 * Resolve this type by a single level, returning the resolved value or {@link #NONE}.
706 	 * <p>Note: The returned {@link ResolvableType} should only be used as an intermediary
707 	 * as it cannot be serialized.
708 	 */
709 	ResolvableType resolveType() {
710 		if (this.type instanceof ParameterizedType) {
711 			return forType(((ParameterizedType) this.type).getRawType(), this.variableResolver);
712 		}
713 		if (this.type instanceof WildcardType) {
714 			Type resolved = resolveBounds(((WildcardType) this.type).getUpperBounds());
715 			if (resolved == null) {
716 				resolved = resolveBounds(((WildcardType) this.type).getLowerBounds());
717 			}
718 			return forType(resolved, this.variableResolver);
719 		}
720 		if (this.type instanceof TypeVariable) {
721 			TypeVariable<?> variable = (TypeVariable<?>) this.type;
722 			// Try default variable resolution
723 			if (this.variableResolver != null) {
724 				ResolvableType resolved = this.variableResolver.resolveVariable(variable);
725 				if (resolved != null) {
726 					return resolved;
727 				}
728 			}
729 			// Fallback to bounds
730 			return forType(resolveBounds(variable.getBounds()), this.variableResolver);
731 		}
732 		return NONE;
733 	}
734 
735 	private Type resolveBounds(Type[] bounds) {
736 		if (ObjectUtils.isEmpty(bounds) || Object.class.equals(bounds[0])) {
737 			return null;
738 		}
739 		return bounds[0];
740 	}
741 
742 	private ResolvableType resolveVariable(TypeVariable<?> variable) {
743 		if (this.type instanceof TypeVariable) {
744 			return resolveType().resolveVariable(variable);
745 		}
746 		if (this.type instanceof ParameterizedType) {
747 			ParameterizedType parameterizedType = (ParameterizedType) this.type;
748 			TypeVariable<?>[] variables = resolve().getTypeParameters();
749 			for (int i = 0; i < variables.length; i++) {
750 				if (ObjectUtils.nullSafeEquals(variables[i].getName(), variable.getName())) {
751 					Type actualType = parameterizedType.getActualTypeArguments()[i];
752 					return forType(actualType, this.variableResolver);
753 				}
754 			}
755 			if (parameterizedType.getOwnerType() != null) {
756 				return forType(parameterizedType.getOwnerType(), this.variableResolver).resolveVariable(variable);
757 			}
758 		}
759 		if (this.variableResolver != null) {
760 			return this.variableResolver.resolveVariable(variable);
761 		}
762 		return null;
763 	}
764 
765 
766 	@Override
767 	public boolean equals(Object other) {
768 		if (this == other) {
769 			return true;
770 		}
771 		if (!(other instanceof ResolvableType)) {
772 			return false;
773 		}
774 		ResolvableType otherType = (ResolvableType) other;
775 		return (ObjectUtils.nullSafeEquals(this.type, otherType.type) &&
776 				ObjectUtils.nullSafeEquals(getSource(), otherType.getSource()) &&
777 				variableResolverSourceEquals(otherType.variableResolver) &&
778 				ObjectUtils.nullSafeEquals(this.componentType, otherType.componentType));
779 	}
780 
781 	@Override
782 	public int hashCode() {
783 		int hashCode = ObjectUtils.nullSafeHashCode(this.type);
784 		hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(getSource());
785 		hashCode = 31 * hashCode + variableResolverSourceHashCode();
786 		hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(this.componentType);
787 		return hashCode;
788 	}
789 
790 	private boolean variableResolverSourceEquals(VariableResolver other) {
791 		if (this.variableResolver == null) {
792 			return (other == null);
793 		}
794 		if (other == null) {
795 			return false;
796 		}
797 		return ObjectUtils.nullSafeEquals(this.variableResolver.getSource(), other.getSource());
798 	}
799 
800 	private int variableResolverSourceHashCode() {
801 		int hashCode = 0;
802 		if (this.variableResolver != null) {
803 			hashCode = ObjectUtils.nullSafeHashCode(this.variableResolver.getSource());
804 		}
805 		return hashCode;
806 	}
807 
808 	/**
809 	 * Adapts this {@link ResolvableType} to a {@link VariableResolver}.
810 	 */
811 	VariableResolver asVariableResolver() {
812 		if (this == NONE) {
813 			return null;
814 		}
815 		return new DefaultVariableResolver();
816 	}
817 
818 	/**
819 	 * Custom serialization support for {@link #NONE}.
820 	 */
821 	private Object readResolve() throws ObjectStreamException {
822 		return (this.type == null ? NONE : this);
823 	}
824 
825 	/**
826 	 * Return a String representation of this type in its fully resolved form
827 	 * (including any generic parameters).
828 	 */
829 	@Override
830 	public String toString() {
831 		if (isArray()) {
832 			return getComponentType() + "[]";
833 		}
834 		if (this.resolved == null) {
835 			return "?";
836 		}
837 		if (this.type instanceof TypeVariable) {
838 			TypeVariable<?> variable = (TypeVariable<?>) this.type;
839 			if (this.variableResolver == null || this.variableResolver.resolveVariable(variable) == null) {
840 				// Don't bother with variable boundaries for toString()...
841 				// Can cause infinite recursions in case of self-references
842 				return "?";
843 			}
844 		}
845 		StringBuilder result = new StringBuilder(this.resolved.getName());
846 		if (hasGenerics()) {
847 			result.append('<');
848 			result.append(StringUtils.arrayToDelimitedString(getGenerics(), ", "));
849 			result.append('>');
850 		}
851 		return result.toString();
852 	}
853 
854 
855 	// Factory methods
856 
857 	/**
858 	 * Return a {@link ResolvableType} for the specified {@link Class},
859 	 * using the full generic type information for assignability checks.
860 	 * For example: {@code ResolvableType.forClass(MyArrayList.class)}.
861 	 * @param sourceClass the source class (must not be {@code null}
862 	 * @return a {@link ResolvableType} for the specified class
863 	 * @see #forClass(Class, Class)
864 	 * @see #forClassWithGenerics(Class, Class...)
865 	 */
866 	public static ResolvableType forClass(Class<?> sourceClass) {
867 		Assert.notNull(sourceClass, "Source class must not be null");
868 		return forType(sourceClass);
869 	}
870 
871 	/**
872 	 * Return a {@link ResolvableType} for the specified {@link Class}
873 	 * with a given implementation.
874 	 * For example: {@code ResolvableType.forClass(List.class, MyArrayList.class)}.
875 	 * @param sourceClass the source class (must not be {@code null}
876 	 * @param implementationClass the implementation class
877 	 * @return a {@link ResolvableType} for the specified class backed by the given
878 	 * implementation class
879 	 * @see #forClass(Class)
880 	 * @see #forClassWithGenerics(Class, Class...)
881 	 */
882 	public static ResolvableType forClass(Class<?> sourceClass, Class<?> implementationClass) {
883 		Assert.notNull(sourceClass, "Source class must not be null");
884 		ResolvableType asType = forType(implementationClass).as(sourceClass);
885 		return (asType == NONE ? forType(sourceClass) : asType);
886 	}
887 
888 	/**
889 	 * Return a {@link ResolvableType} for the specified {@link Class} with pre-declared generics.
890 	 * @param sourceClass the source class
891 	 * @param generics the generics of the class
892 	 * @return a {@link ResolvableType} for the specific class and generics
893 	 * @see #forClassWithGenerics(Class, ResolvableType...)
894 	 */
895 	public static ResolvableType forClassWithGenerics(Class<?> sourceClass, Class<?>... generics) {
896 		Assert.notNull(sourceClass, "Source class must not be null");
897 		Assert.notNull(generics, "Generics must not be null");
898 		ResolvableType[] resolvableGenerics = new ResolvableType[generics.length];
899 		for (int i = 0; i < generics.length; i++) {
900 			resolvableGenerics[i] = forClass(generics[i]);
901 		}
902 		return forClassWithGenerics(sourceClass, resolvableGenerics);
903 	}
904 
905 	/**
906 	 * Return a {@link ResolvableType} for the specified {@link Class} with pre-declared generics.
907 	 * @param sourceClass the source class
908 	 * @param generics the generics of the class
909 	 * @return a {@link ResolvableType} for the specific class and generics
910 	 * @see #forClassWithGenerics(Class, Class...)
911 	 */
912 	public static ResolvableType forClassWithGenerics(Class<?> sourceClass, ResolvableType... generics) {
913 		Assert.notNull(sourceClass, "Source class must not be null");
914 		Assert.notNull(generics, "Generics must not be null");
915 		TypeVariable<?>[] variables = sourceClass.getTypeParameters();
916 		Assert.isTrue(variables.length == generics.length, "Mismatched number of generics specified");
917 		return forType(sourceClass, new TypeVariablesVariableResolver(variables, generics));
918 	}
919 
920 	/**
921 	 * Return a {@link ResolvableType} for the specified {@link Field}.
922 	 * @param field the source field
923 	 * @return a {@link ResolvableType} for the specified field
924 	 * @see #forField(Field, Class)
925 	 */
926 	public static ResolvableType forField(Field field) {
927 		Assert.notNull(field, "Field must not be null");
928 		return forType(null, new FieldTypeProvider(field), null);
929 	}
930 
931 	/**
932 	 * Return a {@link ResolvableType} for the specified {@link Field} with a given
933 	 * implementation.
934 	 * <p>Use this variant when the class that declares the field includes generic
935 	 * parameter variables that are satisfied by the implementation class.
936 	 * @param field the source field
937 	 * @param implementationClass the implementation class
938 	 * @return a {@link ResolvableType} for the specified field
939 	 * @see #forField(Field)
940 	 */
941 	public static ResolvableType forField(Field field, Class<?> implementationClass) {
942 		Assert.notNull(field, "Field must not be null");
943 		ResolvableType owner = forType(implementationClass).as(field.getDeclaringClass());
944 		return forType(null, new FieldTypeProvider(field), owner.asVariableResolver());
945 	}
946 
947 	/**
948 	 * Return a {@link ResolvableType} for the specified {@link Field} with a given
949 	 * implementation.
950 	 * <p>Use this variant when the class that declares the field includes generic
951 	 * parameter variables that are satisfied by the implementation type.
952 	 * @param field the source field
953 	 * @param implementationType the implementation type
954 	 * @return a {@link ResolvableType} for the specified field
955 	 * @see #forField(Field)
956 	 */
957 	public static ResolvableType forField(Field field, ResolvableType implementationType) {
958 		Assert.notNull(field, "Field must not be null");
959 		implementationType = (implementationType == null ? NONE : implementationType);
960 		ResolvableType owner = implementationType.as(field.getDeclaringClass());
961 		return forType(null, new FieldTypeProvider(field), owner.asVariableResolver());
962 	}
963 
964 	/**
965 	 * Return a {@link ResolvableType} for the specified {@link Field} with the
966 	 * given nesting level.
967 	 * @param field the source field
968 	 * @param nestingLevel the nesting level (1 for the outer level; 2 for a nested
969 	 * generic type; etc)
970 	 * @see #forField(Field)
971 	 */
972 	public static ResolvableType forField(Field field, int nestingLevel) {
973 		Assert.notNull(field, "Field must not be null");
974 		return forType(null, new FieldTypeProvider(field), null).getNested(nestingLevel);
975 	}
976 
977 	/**
978 	 * Return a {@link ResolvableType} for the specified {@link Field} with a given
979 	 * implementation and the given nesting level.
980 	 * <p>Use this variant when the class that declares the field includes generic
981 	 * parameter variables that are satisfied by the implementation class.
982 	 * @param field the source field
983 	 * @param nestingLevel the nesting level (1 for the outer level; 2 for a nested
984 	 * generic type; etc)
985 	 * @param implementationClass the implementation class
986 	 * @return a {@link ResolvableType} for the specified field
987 	 * @see #forField(Field)
988 	 */
989 	public static ResolvableType forField(Field field, int nestingLevel, Class<?> implementationClass) {
990 		Assert.notNull(field, "Field must not be null");
991 		ResolvableType owner = forType(implementationClass).as(field.getDeclaringClass());
992 		return forType(null, new FieldTypeProvider(field), owner.asVariableResolver()).getNested(nestingLevel);
993 	}
994 
995 	/**
996 	 * Return a {@link ResolvableType} for the specified {@link Constructor} parameter.
997 	 * @param constructor the source constructor (must not be {@code null})
998 	 * @param parameterIndex the parameter index
999 	 * @return a {@link ResolvableType} for the specified constructor parameter
1000 	 * @see #forConstructorParameter(Constructor, int, Class)
1001 	 */
1002 	public static ResolvableType forConstructorParameter(Constructor<?> constructor, int parameterIndex) {
1003 		Assert.notNull(constructor, "Constructor must not be null");
1004 		return forMethodParameter(new MethodParameter(constructor, parameterIndex));
1005 	}
1006 
1007 	/**
1008 	 * Return a {@link ResolvableType} for the specified {@link Constructor} parameter
1009 	 * with a given implementation. Use this variant when the class that declares the
1010 	 * constructor includes generic parameter variables that are satisfied by the
1011 	 * implementation class.
1012 	 * @param constructor the source constructor (must not be {@code null})
1013 	 * @param parameterIndex the parameter index
1014 	 * @param implementationClass the implementation class
1015 	 * @return a {@link ResolvableType} for the specified constructor parameter
1016 	 * @see #forConstructorParameter(Constructor, int)
1017 	 */
1018 	public static ResolvableType forConstructorParameter(Constructor<?> constructor, int parameterIndex,
1019 			Class<?> implementationClass) {
1020 
1021 		Assert.notNull(constructor, "Constructor must not be null");
1022 		MethodParameter methodParameter = new MethodParameter(constructor, parameterIndex);
1023 		methodParameter.setContainingClass(implementationClass);
1024 		return forMethodParameter(methodParameter);
1025 	}
1026 
1027 	/**
1028 	 * Return a {@link ResolvableType} for the specified {@link Method} return type.
1029 	 * @param method the source for the method return type
1030 	 * @return a {@link ResolvableType} for the specified method return
1031 	 * @see #forMethodReturnType(Method, Class)
1032 	 */
1033 	public static ResolvableType forMethodReturnType(Method method) {
1034 		Assert.notNull(method, "Method must not be null");
1035 		return forMethodParameter(MethodParameter.forMethodOrConstructor(method, -1));
1036 	}
1037 
1038 	/**
1039 	 * Return a {@link ResolvableType} for the specified {@link Method} return type.
1040 	 * Use this variant when the class that declares the method includes generic
1041 	 * parameter variables that are satisfied by the implementation class.
1042 	 * @param method the source for the method return type
1043 	 * @param implementationClass the implementation class
1044 	 * @return a {@link ResolvableType} for the specified method return
1045 	 * @see #forMethodReturnType(Method)
1046 	 */
1047 	public static ResolvableType forMethodReturnType(Method method, Class<?> implementationClass) {
1048 		Assert.notNull(method, "Method must not be null");
1049 		MethodParameter methodParameter = MethodParameter.forMethodOrConstructor(method, -1);
1050 		methodParameter.setContainingClass(implementationClass);
1051 		return forMethodParameter(methodParameter);
1052 	}
1053 
1054 	/**
1055 	 * Return a {@link ResolvableType} for the specified {@link Method} parameter.
1056 	 * @param method the source method (must not be {@code null})
1057 	 * @param parameterIndex the parameter index
1058 	 * @return a {@link ResolvableType} for the specified method parameter
1059 	 * @see #forMethodParameter(Method, int, Class)
1060 	 * @see #forMethodParameter(MethodParameter)
1061 	 */
1062 	public static ResolvableType forMethodParameter(Method method, int parameterIndex) {
1063 		Assert.notNull(method, "Method must not be null");
1064 		return forMethodParameter(new MethodParameter(method, parameterIndex));
1065 	}
1066 
1067 	/**
1068 	 * Return a {@link ResolvableType} for the specified {@link Method} parameter with a
1069 	 * given implementation. Use this variant when the class that declares the method
1070 	 * includes generic parameter variables that are satisfied by the implementation class.
1071 	 * @param method the source method (must not be {@code null})
1072 	 * @param parameterIndex the parameter index
1073 	 * @param implementationClass the implementation class
1074 	 * @return a {@link ResolvableType} for the specified method parameter
1075 	 * @see #forMethodParameter(Method, int, Class)
1076 	 * @see #forMethodParameter(MethodParameter)
1077 	 */
1078 	public static ResolvableType forMethodParameter(Method method, int parameterIndex, Class<?> implementationClass) {
1079 		Assert.notNull(method, "Method must not be null");
1080 		MethodParameter methodParameter = new MethodParameter(method, parameterIndex);
1081 		methodParameter.setContainingClass(implementationClass);
1082 		return forMethodParameter(methodParameter);
1083 	}
1084 
1085 	/**
1086 	 * Return a {@link ResolvableType} for the specified {@link MethodParameter}.
1087 	 * @param methodParameter the source method parameter (must not be {@code null})
1088 	 * @return a {@link ResolvableType} for the specified method parameter
1089 	 * @see #forMethodParameter(Method, int)
1090 	 */
1091 	public static ResolvableType forMethodParameter(MethodParameter methodParameter) {
1092 		return forMethodParameter(methodParameter, (Type) null);
1093 	}
1094 
1095 	/**
1096 	 * Return a {@link ResolvableType} for the specified {@link MethodParameter} with a
1097 	 * given implementation type. Use this variant when the class that declares the method
1098 	 * includes generic parameter variables that are satisfied by the implementation type.
1099 	 * @param methodParameter the source method parameter (must not be {@code null})
1100 	 * @param implementationType the implementation type
1101 	 * @return a {@link ResolvableType} for the specified method parameter
1102 	 * @see #forMethodParameter(MethodParameter)
1103 	 */
1104 	public static ResolvableType forMethodParameter(MethodParameter methodParameter, ResolvableType implementationType) {
1105 		Assert.notNull(methodParameter, "MethodParameter must not be null");
1106 		implementationType = (implementationType == null ? forType(methodParameter.getContainingClass()) : implementationType);
1107 		ResolvableType owner = implementationType.as(methodParameter.getDeclaringClass());
1108 		return forType(null, new MethodParameterTypeProvider(methodParameter),
1109 				owner.asVariableResolver()).getNested(methodParameter.getNestingLevel(),
1110 				methodParameter.typeIndexesPerLevel);
1111 	}
1112 
1113 	/**
1114 	 * Return a {@link ResolvableType} for the specified {@link MethodParameter},
1115 	 * overriding the target type to resolve with a specific given type.
1116 	 * @param methodParameter the source method parameter (must not be {@code null})
1117 	 * @param targetType the type to resolve (a part of the method parameter's type)
1118 	 * @return a {@link ResolvableType} for the specified method parameter
1119 	 * @see #forMethodParameter(Method, int)
1120 	 */
1121 	public static ResolvableType forMethodParameter(MethodParameter methodParameter, Type targetType) {
1122 		Assert.notNull(methodParameter, "MethodParameter must not be null");
1123 		ResolvableType owner = forType(methodParameter.getContainingClass()).as(methodParameter.getDeclaringClass());
1124 		return forType(targetType, new MethodParameterTypeProvider(methodParameter), owner.asVariableResolver()).
1125 				getNested(methodParameter.getNestingLevel(), methodParameter.typeIndexesPerLevel);
1126 	}
1127 
1128 	/**
1129 	 * Return a {@link ResolvableType} as a array of the specified {@code componentType}.
1130 	 * @param componentType the component type
1131 	 * @return a {@link ResolvableType} as an array of the specified component type
1132 	 */
1133 	public static ResolvableType forArrayComponent(ResolvableType componentType) {
1134 		Assert.notNull(componentType, "componentType must not be null");
1135 		Class<?> arrayClass = Array.newInstance(componentType.resolve(), 0).getClass();
1136 		return new ResolvableType(arrayClass, null, null, componentType);
1137 	}
1138 
1139 	private static ResolvableType[] forTypes(Type[] types, VariableResolver owner) {
1140 		ResolvableType[] result = new ResolvableType[types.length];
1141 		for (int i = 0; i < types.length; i++) {
1142 			result[i] = forType(types[i], owner);
1143 		}
1144 		return result;
1145 	}
1146 
1147 	/**
1148 	 * Return a {@link ResolvableType} for the specified {@link Type}.
1149 	 * Note: The resulting {@link ResolvableType} may not be {@link Serializable}.
1150 	 * @param type the source type or {@code null}
1151 	 * @return a {@link ResolvableType} for the specified {@link Type}
1152 	 * @see #forType(Type, ResolvableType)
1153 	 */
1154 	public static ResolvableType forType(Type type) {
1155 		return forType(type, null, null);
1156 	}
1157 
1158 	/**
1159 	 * Return a {@link ResolvableType} for the specified {@link Type} backed by the given
1160 	 * owner type. Note: The resulting {@link ResolvableType} may not be {@link Serializable}.
1161 	 * @param type the source type or {@code null}
1162 	 * @param owner the owner type used to resolve variables
1163 	 * @return a {@link ResolvableType} for the specified {@link Type} and owner
1164 	 * @see #forType(Type)
1165 	 */
1166 	public static ResolvableType forType(Type type, ResolvableType owner) {
1167 		VariableResolver variableResolver = null;
1168 		if (owner != null) {
1169 			variableResolver = owner.asVariableResolver();
1170 		}
1171 		return forType(type, variableResolver);
1172 	}
1173 
1174 	/**
1175 	 * Return a {@link ResolvableType} for the specified {@link Type} backed by a given
1176 	 * {@link VariableResolver}.
1177 	 * @param type the source type or {@code null}
1178 	 * @param variableResolver the variable resolver or {@code null}
1179 	 * @return a {@link ResolvableType} for the specified {@link Type} and {@link VariableResolver}
1180 	 */
1181 	static ResolvableType forType(Type type, VariableResolver variableResolver) {
1182 		return forType(type, null, variableResolver);
1183 	}
1184 
1185 	/**
1186 	 * Return a {@link ResolvableType} for the specified {@link Type} backed by a given
1187 	 * {@link VariableResolver}.
1188 	 * @param type the source type or {@code null}
1189 	 * @param typeProvider the type provider or {@code null}
1190 	 * @param variableResolver the variable resolver or {@code null}
1191 	 * @return a {@link ResolvableType} for the specified {@link Type} and {@link VariableResolver}
1192 	 */
1193 	static ResolvableType forType(Type type, TypeProvider typeProvider, VariableResolver variableResolver) {
1194 		if (type == null && typeProvider != null) {
1195 			type = SerializableTypeWrapper.forTypeProvider(typeProvider);
1196 		}
1197 		if (type == null) {
1198 			return NONE;
1199 		}
1200 
1201 		// Purge empty entries on access since we don't have a clean-up thread or the like.
1202 		cache.purgeUnreferencedEntries();
1203 
1204 		// For simple Class references, build the wrapper right away -
1205 		// no expensive resolution necessary, so not worth caching...
1206 		if (type instanceof Class) {
1207 			return new ResolvableType(type, typeProvider, variableResolver, null);
1208 		}
1209 
1210 		// Check the cache - we may have a ResolvableType which has been resolved before...
1211 		ResolvableType key = new ResolvableType(type, typeProvider, variableResolver);
1212 		ResolvableType resolvableType = cache.get(key);
1213 		if (resolvableType == null) {
1214 			resolvableType = new ResolvableType(type, typeProvider, variableResolver, null);
1215 			cache.put(resolvableType, resolvableType);
1216 		}
1217 		return resolvableType;
1218 	}
1219 
1220 
1221 	/**
1222 	 * Strategy interface used to resolve {@link TypeVariable}s.
1223 	 */
1224 	static interface VariableResolver extends Serializable {
1225 
1226 		/**
1227 		 * Return the source of the resolver (used for hashCode and equals).
1228 		 */
1229 		Object getSource();
1230 
1231 		/**
1232 		 * Resolve the specified variable.
1233 		 * @param variable the variable to resolve
1234 		 * @return the resolved variable or {@code null}
1235 		 */
1236 		ResolvableType resolveVariable(TypeVariable<?> variable);
1237 	}
1238 
1239 
1240 	@SuppressWarnings("serial")
1241 	private class DefaultVariableResolver implements VariableResolver {
1242 
1243 		@Override
1244 		public ResolvableType resolveVariable(TypeVariable<?> variable) {
1245 			return ResolvableType.this.resolveVariable(variable);
1246 		}
1247 
1248 		@Override
1249 		public Object getSource() {
1250 			return ResolvableType.this;
1251 		}
1252 	}
1253 
1254 
1255 	@SuppressWarnings("serial")
1256 	private static class TypeVariablesVariableResolver implements VariableResolver {
1257 
1258 		private final TypeVariable<?>[] variables;
1259 
1260 		private final ResolvableType[] generics;
1261 
1262 		public TypeVariablesVariableResolver(TypeVariable<?>[] variables, ResolvableType[] generics) {
1263 			this.variables = variables;
1264 			this.generics = generics;
1265 		}
1266 
1267 		@Override
1268 		public ResolvableType resolveVariable(TypeVariable<?> variable) {
1269 			for (int i = 0; i < this.variables.length; i++) {
1270 				if (SerializableTypeWrapper.unwrap(this.variables[i]).equals(
1271 						SerializableTypeWrapper.unwrap(variable))) {
1272 					return this.generics[i];
1273 				}
1274 			}
1275 			return null;
1276 		}
1277 
1278 		@Override
1279 		public Object getSource() {
1280 			return this.generics;
1281 		}
1282 	}
1283 
1284 
1285 	/**
1286 	 * Internal helper to handle bounds from {@link WildcardType}s.
1287 	 */
1288 	private static class WildcardBounds {
1289 
1290 		private final Kind kind;
1291 
1292 		private final ResolvableType[] bounds;
1293 
1294 		/**
1295 		 * Internal constructor to create a new {@link WildcardBounds} instance.
1296 		 * @param kind the kind of bounds
1297 		 * @param bounds the bounds
1298 		 * @see #get(ResolvableType)
1299 		 */
1300 		public WildcardBounds(Kind kind, ResolvableType[] bounds) {
1301 			this.kind = kind;
1302 			this.bounds = bounds;
1303 		}
1304 
1305 		/**
1306 		 * Return {@code true} if this bounds is the same kind as the specified bounds.
1307 		 */
1308 		public boolean isSameKind(WildcardBounds bounds) {
1309 			return this.kind == bounds.kind;
1310 		}
1311 
1312 		/**
1313 		 * Return {@code true} if this bounds is assignable to all the specified types.
1314 		 * @param types the types to test against
1315 		 * @return {@code true} if this bounds is assignable to all types
1316 		 */
1317 		public boolean isAssignableFrom(ResolvableType... types) {
1318 			for (ResolvableType bound : this.bounds) {
1319 				for (ResolvableType type : types) {
1320 					if (!isAssignable(bound, type)) {
1321 						return false;
1322 					}
1323 				}
1324 			}
1325 			return true;
1326 		}
1327 
1328 		private boolean isAssignable(ResolvableType source, ResolvableType from) {
1329 			return (this.kind == Kind.UPPER ? source.isAssignableFrom(from) : from.isAssignableFrom(source));
1330 		}
1331 
1332 		/**
1333 		 * Return the underlying bounds.
1334 		 */
1335 		public ResolvableType[] getBounds() {
1336 			return this.bounds;
1337 		}
1338 
1339 		/**
1340 		 * Get a {@link WildcardBounds} instance for the specified type, returning
1341 		 * {@code null} if the specified type cannot be resolved to a {@link WildcardType}.
1342 		 * @param type the source type
1343 		 * @return a {@link WildcardBounds} instance or {@code null}
1344 		 */
1345 		public static WildcardBounds get(ResolvableType type) {
1346 			ResolvableType resolveToWildcard = type;
1347 			while (!(resolveToWildcard.getType() instanceof WildcardType)) {
1348 				if (resolveToWildcard == NONE) {
1349 					return null;
1350 				}
1351 				resolveToWildcard = resolveToWildcard.resolveType();
1352 			}
1353 			WildcardType wildcardType = (WildcardType) resolveToWildcard.type;
1354 			Kind boundsType = (wildcardType.getLowerBounds().length > 0 ? Kind.LOWER : Kind.UPPER);
1355 			Type[] bounds = boundsType == Kind.UPPER ? wildcardType.getUpperBounds() : wildcardType.getLowerBounds();
1356 			ResolvableType[] resolvableBounds = new ResolvableType[bounds.length];
1357 			for (int i = 0; i < bounds.length; i++) {
1358 				resolvableBounds[i] = ResolvableType.forType(bounds[i], type.variableResolver);
1359 			}
1360 			return new WildcardBounds(boundsType, resolvableBounds);
1361 		}
1362 
1363 		/**
1364 		 * The various kinds of bounds.
1365 		 */
1366 		static enum Kind {UPPER, LOWER}
1367 	}
1368 
1369 }