001/* 002 * Copyright 2002-2020 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.core; 018 019import java.io.Serializable; 020import java.lang.reflect.Array; 021import java.lang.reflect.Constructor; 022import java.lang.reflect.Field; 023import java.lang.reflect.GenericArrayType; 024import java.lang.reflect.Method; 025import java.lang.reflect.ParameterizedType; 026import java.lang.reflect.Type; 027import java.lang.reflect.TypeVariable; 028import java.lang.reflect.WildcardType; 029import java.util.Arrays; 030import java.util.Collection; 031import java.util.IdentityHashMap; 032import java.util.Map; 033import java.util.StringJoiner; 034 035import org.springframework.core.SerializableTypeWrapper.FieldTypeProvider; 036import org.springframework.core.SerializableTypeWrapper.MethodParameterTypeProvider; 037import org.springframework.core.SerializableTypeWrapper.TypeProvider; 038import org.springframework.lang.Nullable; 039import org.springframework.util.Assert; 040import org.springframework.util.ClassUtils; 041import org.springframework.util.ConcurrentReferenceHashMap; 042import org.springframework.util.ObjectUtils; 043import org.springframework.util.StringUtils; 044 045/** 046 * Encapsulates a Java {@link java.lang.reflect.Type}, providing access to 047 * {@link #getSuperType() supertypes}, {@link #getInterfaces() interfaces}, and 048 * {@link #getGeneric(int...) generic parameters} along with the ability to ultimately 049 * {@link #resolve() resolve} to a {@link java.lang.Class}. 050 * 051 * <p>{@code ResolvableTypes} may be obtained from {@link #forField(Field) fields}, 052 * {@link #forMethodParameter(Method, int) method parameters}, 053 * {@link #forMethodReturnType(Method) method returns} or 054 * {@link #forClass(Class) classes}. Most methods on this class will themselves return 055 * {@link ResolvableType ResolvableTypes}, allowing easy navigation. For example: 056 * <pre class="code"> 057 * private HashMap<Integer, List<String>> myMap; 058 * 059 * public void example() { 060 * ResolvableType t = ResolvableType.forField(getClass().getDeclaredField("myMap")); 061 * t.getSuperType(); // AbstractMap<Integer, List<String>> 062 * t.asMap(); // Map<Integer, List<String>> 063 * t.getGeneric(0).resolve(); // Integer 064 * t.getGeneric(1).resolve(); // List 065 * t.getGeneric(1); // List<String> 066 * t.resolveGeneric(1, 0); // String 067 * } 068 * </pre> 069 * 070 * @author Phillip Webb 071 * @author Juergen Hoeller 072 * @author Stephane Nicoll 073 * @since 4.0 074 * @see #forField(Field) 075 * @see #forMethodParameter(Method, int) 076 * @see #forMethodReturnType(Method) 077 * @see #forConstructorParameter(Constructor, int) 078 * @see #forClass(Class) 079 * @see #forType(Type) 080 * @see #forInstance(Object) 081 * @see ResolvableTypeProvider 082 */ 083@SuppressWarnings("serial") 084public class ResolvableType implements Serializable { 085 086 /** 087 * {@code ResolvableType} returned when no value is available. {@code NONE} is used 088 * in preference to {@code null} so that multiple method calls can be safely chained. 089 */ 090 public static final ResolvableType NONE = new ResolvableType(EmptyType.INSTANCE, null, null, 0); 091 092 private static final ResolvableType[] EMPTY_TYPES_ARRAY = new ResolvableType[0]; 093 094 private static final ConcurrentReferenceHashMap<ResolvableType, ResolvableType> cache = 095 new ConcurrentReferenceHashMap<>(256); 096 097 098 /** 099 * The underlying Java type being managed. 100 */ 101 private final Type type; 102 103 /** 104 * Optional provider for the type. 105 */ 106 @Nullable 107 private final TypeProvider typeProvider; 108 109 /** 110 * The {@code VariableResolver} to use or {@code null} if no resolver is available. 111 */ 112 @Nullable 113 private final VariableResolver variableResolver; 114 115 /** 116 * The component type for an array or {@code null} if the type should be deduced. 117 */ 118 @Nullable 119 private final ResolvableType componentType; 120 121 @Nullable 122 private final Integer hash; 123 124 @Nullable 125 private Class<?> resolved; 126 127 @Nullable 128 private volatile ResolvableType superType; 129 130 @Nullable 131 private volatile ResolvableType[] interfaces; 132 133 @Nullable 134 private volatile ResolvableType[] generics; 135 136 137 /** 138 * Private constructor used to create a new {@link ResolvableType} for cache key purposes, 139 * with no upfront resolution. 140 */ 141 private ResolvableType( 142 Type type, @Nullable TypeProvider typeProvider, @Nullable VariableResolver variableResolver) { 143 144 this.type = type; 145 this.typeProvider = typeProvider; 146 this.variableResolver = variableResolver; 147 this.componentType = null; 148 this.hash = calculateHashCode(); 149 this.resolved = null; 150 } 151 152 /** 153 * Private constructor used to create a new {@link ResolvableType} for cache value purposes, 154 * with upfront resolution and a pre-calculated hash. 155 * @since 4.2 156 */ 157 private ResolvableType(Type type, @Nullable TypeProvider typeProvider, 158 @Nullable VariableResolver variableResolver, @Nullable Integer hash) { 159 160 this.type = type; 161 this.typeProvider = typeProvider; 162 this.variableResolver = variableResolver; 163 this.componentType = null; 164 this.hash = hash; 165 this.resolved = resolveClass(); 166 } 167 168 /** 169 * Private constructor used to create a new {@link ResolvableType} for uncached purposes, 170 * with upfront resolution but lazily calculated hash. 171 */ 172 private ResolvableType(Type type, @Nullable TypeProvider typeProvider, 173 @Nullable VariableResolver variableResolver, @Nullable ResolvableType componentType) { 174 175 this.type = type; 176 this.typeProvider = typeProvider; 177 this.variableResolver = variableResolver; 178 this.componentType = componentType; 179 this.hash = null; 180 this.resolved = resolveClass(); 181 } 182 183 /** 184 * Private constructor used to create a new {@link ResolvableType} on a {@link Class} basis. 185 * Avoids all {@code instanceof} checks in order to create a straight {@link Class} wrapper. 186 * @since 4.2 187 */ 188 private ResolvableType(@Nullable Class<?> clazz) { 189 this.resolved = (clazz != null ? clazz : Object.class); 190 this.type = this.resolved; 191 this.typeProvider = null; 192 this.variableResolver = null; 193 this.componentType = null; 194 this.hash = null; 195 } 196 197 198 /** 199 * Return the underling Java {@link Type} being managed. 200 */ 201 public Type getType() { 202 return SerializableTypeWrapper.unwrap(this.type); 203 } 204 205 /** 206 * Return the underlying Java {@link Class} being managed, if available; 207 * otherwise {@code null}. 208 */ 209 @Nullable 210 public Class<?> getRawClass() { 211 if (this.type == this.resolved) { 212 return this.resolved; 213 } 214 Type rawType = this.type; 215 if (rawType instanceof ParameterizedType) { 216 rawType = ((ParameterizedType) rawType).getRawType(); 217 } 218 return (rawType instanceof Class ? (Class<?>) rawType : null); 219 } 220 221 /** 222 * Return the underlying source of the resolvable type. Will return a {@link Field}, 223 * {@link MethodParameter} or {@link Type} depending on how the {@link ResolvableType} 224 * was constructed. With the exception of the {@link #NONE} constant, this method will 225 * never return {@code null}. This method is primarily to provide access to additional 226 * type information or meta-data that alternative JVM languages may provide. 227 */ 228 public Object getSource() { 229 Object source = (this.typeProvider != null ? this.typeProvider.getSource() : null); 230 return (source != null ? source : this.type); 231 } 232 233 /** 234 * Return this type as a resolved {@code Class}, falling back to 235 * {@link java.lang.Object} if no specific class can be resolved. 236 * @return the resolved {@link Class} or the {@code Object} fallback 237 * @since 5.1 238 * @see #getRawClass() 239 * @see #resolve(Class) 240 */ 241 public Class<?> toClass() { 242 return resolve(Object.class); 243 } 244 245 /** 246 * Determine whether the given object is an instance of this {@code ResolvableType}. 247 * @param obj the object to check 248 * @since 4.2 249 * @see #isAssignableFrom(Class) 250 */ 251 public boolean isInstance(@Nullable Object obj) { 252 return (obj != null && isAssignableFrom(obj.getClass())); 253 } 254 255 /** 256 * Determine whether this {@code ResolvableType} is assignable from the 257 * specified other type. 258 * @param other the type to be checked against (as a {@code Class}) 259 * @since 4.2 260 * @see #isAssignableFrom(ResolvableType) 261 */ 262 public boolean isAssignableFrom(Class<?> other) { 263 return isAssignableFrom(forClass(other), null); 264 } 265 266 /** 267 * Determine whether this {@code ResolvableType} is assignable from the 268 * specified other type. 269 * <p>Attempts to follow the same rules as the Java compiler, considering 270 * whether both the {@link #resolve() resolved} {@code Class} is 271 * {@link Class#isAssignableFrom(Class) assignable from} the given type 272 * as well as whether all {@link #getGenerics() generics} are assignable. 273 * @param other the type to be checked against (as a {@code ResolvableType}) 274 * @return {@code true} if the specified other type can be assigned to this 275 * {@code ResolvableType}; {@code false} otherwise 276 */ 277 public boolean isAssignableFrom(ResolvableType other) { 278 return isAssignableFrom(other, null); 279 } 280 281 private boolean isAssignableFrom(ResolvableType other, @Nullable Map<Type, Type> matchedBefore) { 282 Assert.notNull(other, "ResolvableType must not be null"); 283 284 // If we cannot resolve types, we are not assignable 285 if (this == NONE || other == NONE) { 286 return false; 287 } 288 289 // Deal with array by delegating to the component type 290 if (isArray()) { 291 return (other.isArray() && getComponentType().isAssignableFrom(other.getComponentType())); 292 } 293 294 if (matchedBefore != null && matchedBefore.get(this.type) == other.type) { 295 return true; 296 } 297 298 // Deal with wildcard bounds 299 WildcardBounds ourBounds = WildcardBounds.get(this); 300 WildcardBounds typeBounds = WildcardBounds.get(other); 301 302 // In the form X is assignable to <? extends Number> 303 if (typeBounds != null) { 304 return (ourBounds != null && ourBounds.isSameKind(typeBounds) && 305 ourBounds.isAssignableFrom(typeBounds.getBounds())); 306 } 307 308 // In the form <? extends Number> is assignable to X... 309 if (ourBounds != null) { 310 return ourBounds.isAssignableFrom(other); 311 } 312 313 // Main assignability check about to follow 314 boolean exactMatch = (matchedBefore != null); // We're checking nested generic variables now... 315 boolean checkGenerics = true; 316 Class<?> ourResolved = null; 317 if (this.type instanceof TypeVariable) { 318 TypeVariable<?> variable = (TypeVariable<?>) this.type; 319 // Try default variable resolution 320 if (this.variableResolver != null) { 321 ResolvableType resolved = this.variableResolver.resolveVariable(variable); 322 if (resolved != null) { 323 ourResolved = resolved.resolve(); 324 } 325 } 326 if (ourResolved == null) { 327 // Try variable resolution against target type 328 if (other.variableResolver != null) { 329 ResolvableType resolved = other.variableResolver.resolveVariable(variable); 330 if (resolved != null) { 331 ourResolved = resolved.resolve(); 332 checkGenerics = false; 333 } 334 } 335 } 336 if (ourResolved == null) { 337 // Unresolved type variable, potentially nested -> never insist on exact match 338 exactMatch = false; 339 } 340 } 341 if (ourResolved == null) { 342 ourResolved = resolve(Object.class); 343 } 344 Class<?> otherResolved = other.toClass(); 345 346 // We need an exact type match for generics 347 // List<CharSequence> is not assignable from List<String> 348 if (exactMatch ? !ourResolved.equals(otherResolved) : !ClassUtils.isAssignable(ourResolved, otherResolved)) { 349 return false; 350 } 351 352 if (checkGenerics) { 353 // Recursively check each generic 354 ResolvableType[] ourGenerics = getGenerics(); 355 ResolvableType[] typeGenerics = other.as(ourResolved).getGenerics(); 356 if (ourGenerics.length != typeGenerics.length) { 357 return false; 358 } 359 if (matchedBefore == null) { 360 matchedBefore = new IdentityHashMap<>(1); 361 } 362 matchedBefore.put(this.type, other.type); 363 for (int i = 0; i < ourGenerics.length; i++) { 364 if (!ourGenerics[i].isAssignableFrom(typeGenerics[i], matchedBefore)) { 365 return false; 366 } 367 } 368 } 369 370 return true; 371 } 372 373 /** 374 * Return {@code true} if this type resolves to a Class that represents an array. 375 * @see #getComponentType() 376 */ 377 public boolean isArray() { 378 if (this == NONE) { 379 return false; 380 } 381 return ((this.type instanceof Class && ((Class<?>) this.type).isArray()) || 382 this.type instanceof GenericArrayType || resolveType().isArray()); 383 } 384 385 /** 386 * Return the ResolvableType representing the component type of the array or 387 * {@link #NONE} if this type does not represent an array. 388 * @see #isArray() 389 */ 390 public ResolvableType getComponentType() { 391 if (this == NONE) { 392 return NONE; 393 } 394 if (this.componentType != null) { 395 return this.componentType; 396 } 397 if (this.type instanceof Class) { 398 Class<?> componentType = ((Class<?>) this.type).getComponentType(); 399 return forType(componentType, this.variableResolver); 400 } 401 if (this.type instanceof GenericArrayType) { 402 return forType(((GenericArrayType) this.type).getGenericComponentType(), this.variableResolver); 403 } 404 return resolveType().getComponentType(); 405 } 406 407 /** 408 * Convenience method to return this type as a resolvable {@link Collection} type. 409 * Returns {@link #NONE} if this type does not implement or extend 410 * {@link Collection}. 411 * @see #as(Class) 412 * @see #asMap() 413 */ 414 public ResolvableType asCollection() { 415 return as(Collection.class); 416 } 417 418 /** 419 * Convenience method to return this type as a resolvable {@link Map} type. 420 * Returns {@link #NONE} if this type does not implement or extend 421 * {@link Map}. 422 * @see #as(Class) 423 * @see #asCollection() 424 */ 425 public ResolvableType asMap() { 426 return as(Map.class); 427 } 428 429 /** 430 * Return this type as a {@link ResolvableType} of the specified class. Searches 431 * {@link #getSuperType() supertype} and {@link #getInterfaces() interface} 432 * hierarchies to find a match, returning {@link #NONE} if this type does not 433 * implement or extend the specified class. 434 * @param type the required type (typically narrowed) 435 * @return a {@link ResolvableType} representing this object as the specified 436 * type, or {@link #NONE} if not resolvable as that type 437 * @see #asCollection() 438 * @see #asMap() 439 * @see #getSuperType() 440 * @see #getInterfaces() 441 */ 442 public ResolvableType as(Class<?> type) { 443 if (this == NONE) { 444 return NONE; 445 } 446 Class<?> resolved = resolve(); 447 if (resolved == null || resolved == type) { 448 return this; 449 } 450 for (ResolvableType interfaceType : getInterfaces()) { 451 ResolvableType interfaceAsType = interfaceType.as(type); 452 if (interfaceAsType != NONE) { 453 return interfaceAsType; 454 } 455 } 456 return getSuperType().as(type); 457 } 458 459 /** 460 * Return a {@link ResolvableType} representing the direct supertype of this type. 461 * If no supertype is available this method returns {@link #NONE}. 462 * <p>Note: The resulting {@link ResolvableType} instance may not be {@link Serializable}. 463 * @see #getInterfaces() 464 */ 465 public ResolvableType getSuperType() { 466 Class<?> resolved = resolve(); 467 if (resolved == null) { 468 return NONE; 469 } 470 try { 471 Type superclass = resolved.getGenericSuperclass(); 472 if (superclass == null) { 473 return NONE; 474 } 475 ResolvableType superType = this.superType; 476 if (superType == null) { 477 superType = forType(superclass, this); 478 this.superType = superType; 479 } 480 return superType; 481 } 482 catch (TypeNotPresentException ex) { 483 // Ignore non-present types in generic signature 484 return NONE; 485 } 486 } 487 488 /** 489 * Return a {@link ResolvableType} array representing the direct interfaces 490 * implemented by this type. If this type does not implement any interfaces an 491 * empty array is returned. 492 * <p>Note: The resulting {@link ResolvableType} instances may not be {@link Serializable}. 493 * @see #getSuperType() 494 */ 495 public ResolvableType[] getInterfaces() { 496 Class<?> resolved = resolve(); 497 if (resolved == null) { 498 return EMPTY_TYPES_ARRAY; 499 } 500 ResolvableType[] interfaces = this.interfaces; 501 if (interfaces == null) { 502 Type[] genericIfcs = resolved.getGenericInterfaces(); 503 interfaces = new ResolvableType[genericIfcs.length]; 504 for (int i = 0; i < genericIfcs.length; i++) { 505 interfaces[i] = forType(genericIfcs[i], this); 506 } 507 this.interfaces = interfaces; 508 } 509 return interfaces; 510 } 511 512 /** 513 * Return {@code true} if this type contains generic parameters. 514 * @see #getGeneric(int...) 515 * @see #getGenerics() 516 */ 517 public boolean hasGenerics() { 518 return (getGenerics().length > 0); 519 } 520 521 /** 522 * Return {@code true} if this type contains unresolvable generics only, 523 * that is, no substitute for any of its declared type variables. 524 */ 525 boolean isEntirelyUnresolvable() { 526 if (this == NONE) { 527 return false; 528 } 529 ResolvableType[] generics = getGenerics(); 530 for (ResolvableType generic : generics) { 531 if (!generic.isUnresolvableTypeVariable() && !generic.isWildcardWithoutBounds()) { 532 return false; 533 } 534 } 535 return true; 536 } 537 538 /** 539 * Determine whether the underlying type has any unresolvable generics: 540 * either through an unresolvable type variable on the type itself 541 * or through implementing a generic interface in a raw fashion, 542 * i.e. without substituting that interface's type variables. 543 * The result will be {@code true} only in those two scenarios. 544 */ 545 public boolean hasUnresolvableGenerics() { 546 if (this == NONE) { 547 return false; 548 } 549 ResolvableType[] generics = getGenerics(); 550 for (ResolvableType generic : generics) { 551 if (generic.isUnresolvableTypeVariable() || generic.isWildcardWithoutBounds()) { 552 return true; 553 } 554 } 555 Class<?> resolved = resolve(); 556 if (resolved != null) { 557 try { 558 for (Type genericInterface : resolved.getGenericInterfaces()) { 559 if (genericInterface instanceof Class) { 560 if (forClass((Class<?>) genericInterface).hasGenerics()) { 561 return true; 562 } 563 } 564 } 565 } 566 catch (TypeNotPresentException ex) { 567 // Ignore non-present types in generic signature 568 } 569 return getSuperType().hasUnresolvableGenerics(); 570 } 571 return false; 572 } 573 574 /** 575 * Determine whether the underlying type is a type variable that 576 * cannot be resolved through the associated variable resolver. 577 */ 578 private boolean isUnresolvableTypeVariable() { 579 if (this.type instanceof TypeVariable) { 580 if (this.variableResolver == null) { 581 return true; 582 } 583 TypeVariable<?> variable = (TypeVariable<?>) this.type; 584 ResolvableType resolved = this.variableResolver.resolveVariable(variable); 585 if (resolved == null || resolved.isUnresolvableTypeVariable()) { 586 return true; 587 } 588 } 589 return false; 590 } 591 592 /** 593 * Determine whether the underlying type represents a wildcard 594 * without specific bounds (i.e., equal to {@code ? extends Object}). 595 */ 596 private boolean isWildcardWithoutBounds() { 597 if (this.type instanceof WildcardType) { 598 WildcardType wt = (WildcardType) this.type; 599 if (wt.getLowerBounds().length == 0) { 600 Type[] upperBounds = wt.getUpperBounds(); 601 if (upperBounds.length == 0 || (upperBounds.length == 1 && Object.class == upperBounds[0])) { 602 return true; 603 } 604 } 605 } 606 return false; 607 } 608 609 /** 610 * Return a {@link ResolvableType} for the specified nesting level. 611 * See {@link #getNested(int, Map)} for details. 612 * @param nestingLevel the nesting level 613 * @return the {@link ResolvableType} type, or {@code #NONE} 614 */ 615 public ResolvableType getNested(int nestingLevel) { 616 return getNested(nestingLevel, null); 617 } 618 619 /** 620 * Return a {@link ResolvableType} for the specified nesting level. 621 * <p>The nesting level refers to the specific generic parameter that should be returned. 622 * A nesting level of 1 indicates this type; 2 indicates the first nested generic; 623 * 3 the second; and so on. For example, given {@code List<Set<Integer>>} level 1 refers 624 * to the {@code List}, level 2 the {@code Set}, and level 3 the {@code Integer}. 625 * <p>The {@code typeIndexesPerLevel} map can be used to reference a specific generic 626 * for the given level. For example, an index of 0 would refer to a {@code Map} key; 627 * whereas, 1 would refer to the value. If the map does not contain a value for a 628 * specific level the last generic will be used (e.g. a {@code Map} value). 629 * <p>Nesting levels may also apply to array types; for example given 630 * {@code String[]}, a nesting level of 2 refers to {@code String}. 631 * <p>If a type does not {@link #hasGenerics() contain} generics the 632 * {@link #getSuperType() supertype} hierarchy will be considered. 633 * @param nestingLevel the required nesting level, indexed from 1 for the 634 * current type, 2 for the first nested generic, 3 for the second and so on 635 * @param typeIndexesPerLevel a map containing the generic index for a given 636 * nesting level (may be {@code null}) 637 * @return a {@link ResolvableType} for the nested level, or {@link #NONE} 638 */ 639 public ResolvableType getNested(int nestingLevel, @Nullable Map<Integer, Integer> typeIndexesPerLevel) { 640 ResolvableType result = this; 641 for (int i = 2; i <= nestingLevel; i++) { 642 if (result.isArray()) { 643 result = result.getComponentType(); 644 } 645 else { 646 // Handle derived types 647 while (result != ResolvableType.NONE && !result.hasGenerics()) { 648 result = result.getSuperType(); 649 } 650 Integer index = (typeIndexesPerLevel != null ? typeIndexesPerLevel.get(i) : null); 651 index = (index == null ? result.getGenerics().length - 1 : index); 652 result = result.getGeneric(index); 653 } 654 } 655 return result; 656 } 657 658 /** 659 * Return a {@link ResolvableType} representing the generic parameter for the 660 * given indexes. Indexes are zero based; for example given the type 661 * {@code Map<Integer, List<String>>}, {@code getGeneric(0)} will access the 662 * {@code Integer}. Nested generics can be accessed by specifying multiple indexes; 663 * for example {@code getGeneric(1, 0)} will access the {@code String} from the 664 * nested {@code List}. For convenience, if no indexes are specified the first 665 * generic is returned. 666 * <p>If no generic is available at the specified indexes {@link #NONE} is returned. 667 * @param indexes the indexes that refer to the generic parameter 668 * (may be omitted to return the first generic) 669 * @return a {@link ResolvableType} for the specified generic, or {@link #NONE} 670 * @see #hasGenerics() 671 * @see #getGenerics() 672 * @see #resolveGeneric(int...) 673 * @see #resolveGenerics() 674 */ 675 public ResolvableType getGeneric(@Nullable int... indexes) { 676 ResolvableType[] generics = getGenerics(); 677 if (indexes == null || indexes.length == 0) { 678 return (generics.length == 0 ? NONE : generics[0]); 679 } 680 ResolvableType generic = this; 681 for (int index : indexes) { 682 generics = generic.getGenerics(); 683 if (index < 0 || index >= generics.length) { 684 return NONE; 685 } 686 generic = generics[index]; 687 } 688 return generic; 689 } 690 691 /** 692 * Return an array of {@link ResolvableType ResolvableTypes} representing the generic parameters of 693 * this type. If no generics are available an empty array is returned. If you need to 694 * access a specific generic consider using the {@link #getGeneric(int...)} method as 695 * it allows access to nested generics and protects against 696 * {@code IndexOutOfBoundsExceptions}. 697 * @return an array of {@link ResolvableType ResolvableTypes} representing the generic parameters 698 * (never {@code null}) 699 * @see #hasGenerics() 700 * @see #getGeneric(int...) 701 * @see #resolveGeneric(int...) 702 * @see #resolveGenerics() 703 */ 704 public ResolvableType[] getGenerics() { 705 if (this == NONE) { 706 return EMPTY_TYPES_ARRAY; 707 } 708 ResolvableType[] generics = this.generics; 709 if (generics == null) { 710 if (this.type instanceof Class) { 711 Type[] typeParams = ((Class<?>) this.type).getTypeParameters(); 712 generics = new ResolvableType[typeParams.length]; 713 for (int i = 0; i < generics.length; i++) { 714 generics[i] = ResolvableType.forType(typeParams[i], this); 715 } 716 } 717 else if (this.type instanceof ParameterizedType) { 718 Type[] actualTypeArguments = ((ParameterizedType) this.type).getActualTypeArguments(); 719 generics = new ResolvableType[actualTypeArguments.length]; 720 for (int i = 0; i < actualTypeArguments.length; i++) { 721 generics[i] = forType(actualTypeArguments[i], this.variableResolver); 722 } 723 } 724 else { 725 generics = resolveType().getGenerics(); 726 } 727 this.generics = generics; 728 } 729 return generics; 730 } 731 732 /** 733 * Convenience method that will {@link #getGenerics() get} and 734 * {@link #resolve() resolve} generic parameters. 735 * @return an array of resolved generic parameters (the resulting array 736 * will never be {@code null}, but it may contain {@code null} elements}) 737 * @see #getGenerics() 738 * @see #resolve() 739 */ 740 public Class<?>[] resolveGenerics() { 741 ResolvableType[] generics = getGenerics(); 742 Class<?>[] resolvedGenerics = new Class<?>[generics.length]; 743 for (int i = 0; i < generics.length; i++) { 744 resolvedGenerics[i] = generics[i].resolve(); 745 } 746 return resolvedGenerics; 747 } 748 749 /** 750 * Convenience method that will {@link #getGenerics() get} and {@link #resolve() 751 * resolve} generic parameters, using the specified {@code fallback} if any type 752 * cannot be resolved. 753 * @param fallback the fallback class to use if resolution fails 754 * @return an array of resolved generic parameters 755 * @see #getGenerics() 756 * @see #resolve() 757 */ 758 public Class<?>[] resolveGenerics(Class<?> fallback) { 759 ResolvableType[] generics = getGenerics(); 760 Class<?>[] resolvedGenerics = new Class<?>[generics.length]; 761 for (int i = 0; i < generics.length; i++) { 762 resolvedGenerics[i] = generics[i].resolve(fallback); 763 } 764 return resolvedGenerics; 765 } 766 767 /** 768 * Convenience method that will {@link #getGeneric(int...) get} and 769 * {@link #resolve() resolve} a specific generic parameters. 770 * @param indexes the indexes that refer to the generic parameter 771 * (may be omitted to return the first generic) 772 * @return a resolved {@link Class} or {@code null} 773 * @see #getGeneric(int...) 774 * @see #resolve() 775 */ 776 @Nullable 777 public Class<?> resolveGeneric(int... indexes) { 778 return getGeneric(indexes).resolve(); 779 } 780 781 /** 782 * Resolve this type to a {@link java.lang.Class}, returning {@code null} 783 * if the type cannot be resolved. This method will consider bounds of 784 * {@link TypeVariable TypeVariables} and {@link WildcardType WildcardTypes} if 785 * direct resolution fails; however, bounds of {@code Object.class} will be ignored. 786 * <p>If this method returns a non-null {@code Class} and {@link #hasGenerics()} 787 * returns {@code false}, the given type effectively wraps a plain {@code Class}, 788 * allowing for plain {@code Class} processing if desirable. 789 * @return the resolved {@link Class}, or {@code null} if not resolvable 790 * @see #resolve(Class) 791 * @see #resolveGeneric(int...) 792 * @see #resolveGenerics() 793 */ 794 @Nullable 795 public Class<?> resolve() { 796 return this.resolved; 797 } 798 799 /** 800 * Resolve this type to a {@link java.lang.Class}, returning the specified 801 * {@code fallback} if the type cannot be resolved. This method will consider bounds 802 * of {@link TypeVariable TypeVariables} and {@link WildcardType WildcardTypes} if 803 * direct resolution fails; however, bounds of {@code Object.class} will be ignored. 804 * @param fallback the fallback class to use if resolution fails 805 * @return the resolved {@link Class} or the {@code fallback} 806 * @see #resolve() 807 * @see #resolveGeneric(int...) 808 * @see #resolveGenerics() 809 */ 810 public Class<?> resolve(Class<?> fallback) { 811 return (this.resolved != null ? this.resolved : fallback); 812 } 813 814 @Nullable 815 private Class<?> resolveClass() { 816 if (this.type == EmptyType.INSTANCE) { 817 return null; 818 } 819 if (this.type instanceof Class) { 820 return (Class<?>) this.type; 821 } 822 if (this.type instanceof GenericArrayType) { 823 Class<?> resolvedComponent = getComponentType().resolve(); 824 return (resolvedComponent != null ? Array.newInstance(resolvedComponent, 0).getClass() : null); 825 } 826 return resolveType().resolve(); 827 } 828 829 /** 830 * Resolve this type by a single level, returning the resolved value or {@link #NONE}. 831 * <p>Note: The returned {@link ResolvableType} should only be used as an intermediary 832 * as it cannot be serialized. 833 */ 834 ResolvableType resolveType() { 835 if (this.type instanceof ParameterizedType) { 836 return forType(((ParameterizedType) this.type).getRawType(), this.variableResolver); 837 } 838 if (this.type instanceof WildcardType) { 839 Type resolved = resolveBounds(((WildcardType) this.type).getUpperBounds()); 840 if (resolved == null) { 841 resolved = resolveBounds(((WildcardType) this.type).getLowerBounds()); 842 } 843 return forType(resolved, this.variableResolver); 844 } 845 if (this.type instanceof TypeVariable) { 846 TypeVariable<?> variable = (TypeVariable<?>) this.type; 847 // Try default variable resolution 848 if (this.variableResolver != null) { 849 ResolvableType resolved = this.variableResolver.resolveVariable(variable); 850 if (resolved != null) { 851 return resolved; 852 } 853 } 854 // Fallback to bounds 855 return forType(resolveBounds(variable.getBounds()), this.variableResolver); 856 } 857 return NONE; 858 } 859 860 @Nullable 861 private Type resolveBounds(Type[] bounds) { 862 if (bounds.length == 0 || bounds[0] == Object.class) { 863 return null; 864 } 865 return bounds[0]; 866 } 867 868 @Nullable 869 private ResolvableType resolveVariable(TypeVariable<?> variable) { 870 if (this.type instanceof TypeVariable) { 871 return resolveType().resolveVariable(variable); 872 } 873 if (this.type instanceof ParameterizedType) { 874 ParameterizedType parameterizedType = (ParameterizedType) this.type; 875 Class<?> resolved = resolve(); 876 if (resolved == null) { 877 return null; 878 } 879 TypeVariable<?>[] variables = resolved.getTypeParameters(); 880 for (int i = 0; i < variables.length; i++) { 881 if (ObjectUtils.nullSafeEquals(variables[i].getName(), variable.getName())) { 882 Type actualType = parameterizedType.getActualTypeArguments()[i]; 883 return forType(actualType, this.variableResolver); 884 } 885 } 886 Type ownerType = parameterizedType.getOwnerType(); 887 if (ownerType != null) { 888 return forType(ownerType, this.variableResolver).resolveVariable(variable); 889 } 890 } 891 if (this.type instanceof WildcardType) { 892 ResolvableType resolved = resolveType().resolveVariable(variable); 893 if (resolved != null) { 894 return resolved; 895 } 896 } 897 if (this.variableResolver != null) { 898 return this.variableResolver.resolveVariable(variable); 899 } 900 return null; 901 } 902 903 904 @Override 905 public boolean equals(@Nullable Object other) { 906 if (this == other) { 907 return true; 908 } 909 if (!(other instanceof ResolvableType)) { 910 return false; 911 } 912 913 ResolvableType otherType = (ResolvableType) other; 914 if (!ObjectUtils.nullSafeEquals(this.type, otherType.type)) { 915 return false; 916 } 917 if (this.typeProvider != otherType.typeProvider && 918 (this.typeProvider == null || otherType.typeProvider == null || 919 !ObjectUtils.nullSafeEquals(this.typeProvider.getType(), otherType.typeProvider.getType()))) { 920 return false; 921 } 922 if (this.variableResolver != otherType.variableResolver && 923 (this.variableResolver == null || otherType.variableResolver == null || 924 !ObjectUtils.nullSafeEquals(this.variableResolver.getSource(), otherType.variableResolver.getSource()))) { 925 return false; 926 } 927 if (!ObjectUtils.nullSafeEquals(this.componentType, otherType.componentType)) { 928 return false; 929 } 930 return true; 931 } 932 933 @Override 934 public int hashCode() { 935 return (this.hash != null ? this.hash : calculateHashCode()); 936 } 937 938 private int calculateHashCode() { 939 int hashCode = ObjectUtils.nullSafeHashCode(this.type); 940 if (this.typeProvider != null) { 941 hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(this.typeProvider.getType()); 942 } 943 if (this.variableResolver != null) { 944 hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(this.variableResolver.getSource()); 945 } 946 if (this.componentType != null) { 947 hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(this.componentType); 948 } 949 return hashCode; 950 } 951 952 /** 953 * Adapts this {@link ResolvableType} to a {@link VariableResolver}. 954 */ 955 @Nullable 956 VariableResolver asVariableResolver() { 957 if (this == NONE) { 958 return null; 959 } 960 return new DefaultVariableResolver(this); 961 } 962 963 /** 964 * Custom serialization support for {@link #NONE}. 965 */ 966 private Object readResolve() { 967 return (this.type == EmptyType.INSTANCE ? NONE : this); 968 } 969 970 /** 971 * Return a String representation of this type in its fully resolved form 972 * (including any generic parameters). 973 */ 974 @Override 975 public String toString() { 976 if (isArray()) { 977 return getComponentType() + "[]"; 978 } 979 if (this.resolved == null) { 980 return "?"; 981 } 982 if (this.type instanceof TypeVariable) { 983 TypeVariable<?> variable = (TypeVariable<?>) this.type; 984 if (this.variableResolver == null || this.variableResolver.resolveVariable(variable) == null) { 985 // Don't bother with variable boundaries for toString()... 986 // Can cause infinite recursions in case of self-references 987 return "?"; 988 } 989 } 990 if (hasGenerics()) { 991 return this.resolved.getName() + '<' + StringUtils.arrayToDelimitedString(getGenerics(), ", ") + '>'; 992 } 993 return this.resolved.getName(); 994 } 995 996 997 // Factory methods 998 999 /** 1000 * Return a {@link ResolvableType} for the specified {@link Class}, 1001 * using the full generic type information for assignability checks. 1002 * For example: {@code ResolvableType.forClass(MyArrayList.class)}. 1003 * @param clazz the class to introspect ({@code null} is semantically 1004 * equivalent to {@code Object.class} for typical use cases here) 1005 * @return a {@link ResolvableType} for the specified class 1006 * @see #forClass(Class, Class) 1007 * @see #forClassWithGenerics(Class, Class...) 1008 */ 1009 public static ResolvableType forClass(@Nullable Class<?> clazz) { 1010 return new ResolvableType(clazz); 1011 } 1012 1013 /** 1014 * Return a {@link ResolvableType} for the specified {@link Class}, 1015 * doing assignability checks against the raw class only (analogous to 1016 * {@link Class#isAssignableFrom}, which this serves as a wrapper for. 1017 * For example: {@code ResolvableType.forRawClass(List.class)}. 1018 * @param clazz the class to introspect ({@code null} is semantically 1019 * equivalent to {@code Object.class} for typical use cases here) 1020 * @return a {@link ResolvableType} for the specified class 1021 * @since 4.2 1022 * @see #forClass(Class) 1023 * @see #getRawClass() 1024 */ 1025 public static ResolvableType forRawClass(@Nullable Class<?> clazz) { 1026 return new ResolvableType(clazz) { 1027 @Override 1028 public ResolvableType[] getGenerics() { 1029 return EMPTY_TYPES_ARRAY; 1030 } 1031 @Override 1032 public boolean isAssignableFrom(Class<?> other) { 1033 return (clazz == null || ClassUtils.isAssignable(clazz, other)); 1034 } 1035 @Override 1036 public boolean isAssignableFrom(ResolvableType other) { 1037 Class<?> otherClass = other.resolve(); 1038 return (otherClass != null && (clazz == null || ClassUtils.isAssignable(clazz, otherClass))); 1039 } 1040 }; 1041 } 1042 1043 /** 1044 * Return a {@link ResolvableType} for the specified base type 1045 * (interface or base class) with a given implementation class. 1046 * For example: {@code ResolvableType.forClass(List.class, MyArrayList.class)}. 1047 * @param baseType the base type (must not be {@code null}) 1048 * @param implementationClass the implementation class 1049 * @return a {@link ResolvableType} for the specified base type backed by the 1050 * given implementation class 1051 * @see #forClass(Class) 1052 * @see #forClassWithGenerics(Class, Class...) 1053 */ 1054 public static ResolvableType forClass(Class<?> baseType, Class<?> implementationClass) { 1055 Assert.notNull(baseType, "Base type must not be null"); 1056 ResolvableType asType = forType(implementationClass).as(baseType); 1057 return (asType == NONE ? forType(baseType) : asType); 1058 } 1059 1060 /** 1061 * Return a {@link ResolvableType} for the specified {@link Class} with pre-declared generics. 1062 * @param clazz the class (or interface) to introspect 1063 * @param generics the generics of the class 1064 * @return a {@link ResolvableType} for the specific class and generics 1065 * @see #forClassWithGenerics(Class, ResolvableType...) 1066 */ 1067 public static ResolvableType forClassWithGenerics(Class<?> clazz, Class<?>... generics) { 1068 Assert.notNull(clazz, "Class must not be null"); 1069 Assert.notNull(generics, "Generics array must not be null"); 1070 ResolvableType[] resolvableGenerics = new ResolvableType[generics.length]; 1071 for (int i = 0; i < generics.length; i++) { 1072 resolvableGenerics[i] = forClass(generics[i]); 1073 } 1074 return forClassWithGenerics(clazz, resolvableGenerics); 1075 } 1076 1077 /** 1078 * Return a {@link ResolvableType} for the specified {@link Class} with pre-declared generics. 1079 * @param clazz the class (or interface) to introspect 1080 * @param generics the generics of the class 1081 * @return a {@link ResolvableType} for the specific class and generics 1082 * @see #forClassWithGenerics(Class, Class...) 1083 */ 1084 public static ResolvableType forClassWithGenerics(Class<?> clazz, ResolvableType... generics) { 1085 Assert.notNull(clazz, "Class must not be null"); 1086 Assert.notNull(generics, "Generics array must not be null"); 1087 TypeVariable<?>[] variables = clazz.getTypeParameters(); 1088 Assert.isTrue(variables.length == generics.length, "Mismatched number of generics specified"); 1089 1090 Type[] arguments = new Type[generics.length]; 1091 for (int i = 0; i < generics.length; i++) { 1092 ResolvableType generic = generics[i]; 1093 Type argument = (generic != null ? generic.getType() : null); 1094 arguments[i] = (argument != null && !(argument instanceof TypeVariable) ? argument : variables[i]); 1095 } 1096 1097 ParameterizedType syntheticType = new SyntheticParameterizedType(clazz, arguments); 1098 return forType(syntheticType, new TypeVariablesVariableResolver(variables, generics)); 1099 } 1100 1101 /** 1102 * Return a {@link ResolvableType} for the specified instance. The instance does not 1103 * convey generic information but if it implements {@link ResolvableTypeProvider} a 1104 * more precise {@link ResolvableType} can be used than the simple one based on 1105 * the {@link #forClass(Class) Class instance}. 1106 * @param instance the instance 1107 * @return a {@link ResolvableType} for the specified instance 1108 * @since 4.2 1109 * @see ResolvableTypeProvider 1110 */ 1111 public static ResolvableType forInstance(Object instance) { 1112 Assert.notNull(instance, "Instance must not be null"); 1113 if (instance instanceof ResolvableTypeProvider) { 1114 ResolvableType type = ((ResolvableTypeProvider) instance).getResolvableType(); 1115 if (type != null) { 1116 return type; 1117 } 1118 } 1119 return ResolvableType.forClass(instance.getClass()); 1120 } 1121 1122 /** 1123 * Return a {@link ResolvableType} for the specified {@link Field}. 1124 * @param field the source field 1125 * @return a {@link ResolvableType} for the specified field 1126 * @see #forField(Field, Class) 1127 */ 1128 public static ResolvableType forField(Field field) { 1129 Assert.notNull(field, "Field must not be null"); 1130 return forType(null, new FieldTypeProvider(field), null); 1131 } 1132 1133 /** 1134 * Return a {@link ResolvableType} for the specified {@link Field} with a given 1135 * implementation. 1136 * <p>Use this variant when the class that declares the field includes generic 1137 * parameter variables that are satisfied by the implementation class. 1138 * @param field the source field 1139 * @param implementationClass the implementation class 1140 * @return a {@link ResolvableType} for the specified field 1141 * @see #forField(Field) 1142 */ 1143 public static ResolvableType forField(Field field, Class<?> implementationClass) { 1144 Assert.notNull(field, "Field must not be null"); 1145 ResolvableType owner = forType(implementationClass).as(field.getDeclaringClass()); 1146 return forType(null, new FieldTypeProvider(field), owner.asVariableResolver()); 1147 } 1148 1149 /** 1150 * Return a {@link ResolvableType} for the specified {@link Field} with a given 1151 * implementation. 1152 * <p>Use this variant when the class that declares the field includes generic 1153 * parameter variables that are satisfied by the implementation type. 1154 * @param field the source field 1155 * @param implementationType the implementation type 1156 * @return a {@link ResolvableType} for the specified field 1157 * @see #forField(Field) 1158 */ 1159 public static ResolvableType forField(Field field, @Nullable ResolvableType implementationType) { 1160 Assert.notNull(field, "Field must not be null"); 1161 ResolvableType owner = (implementationType != null ? implementationType : NONE); 1162 owner = owner.as(field.getDeclaringClass()); 1163 return forType(null, new FieldTypeProvider(field), owner.asVariableResolver()); 1164 } 1165 1166 /** 1167 * Return a {@link ResolvableType} for the specified {@link Field} with the 1168 * given nesting level. 1169 * @param field the source field 1170 * @param nestingLevel the nesting level (1 for the outer level; 2 for a nested 1171 * generic type; etc) 1172 * @see #forField(Field) 1173 */ 1174 public static ResolvableType forField(Field field, int nestingLevel) { 1175 Assert.notNull(field, "Field must not be null"); 1176 return forType(null, new FieldTypeProvider(field), null).getNested(nestingLevel); 1177 } 1178 1179 /** 1180 * Return a {@link ResolvableType} for the specified {@link Field} with a given 1181 * implementation and the given nesting level. 1182 * <p>Use this variant when the class that declares the field includes generic 1183 * parameter variables that are satisfied by the implementation class. 1184 * @param field the source field 1185 * @param nestingLevel the nesting level (1 for the outer level; 2 for a nested 1186 * generic type; etc) 1187 * @param implementationClass the implementation class 1188 * @return a {@link ResolvableType} for the specified field 1189 * @see #forField(Field) 1190 */ 1191 public static ResolvableType forField(Field field, int nestingLevel, @Nullable Class<?> implementationClass) { 1192 Assert.notNull(field, "Field must not be null"); 1193 ResolvableType owner = forType(implementationClass).as(field.getDeclaringClass()); 1194 return forType(null, new FieldTypeProvider(field), owner.asVariableResolver()).getNested(nestingLevel); 1195 } 1196 1197 /** 1198 * Return a {@link ResolvableType} for the specified {@link Constructor} parameter. 1199 * @param constructor the source constructor (must not be {@code null}) 1200 * @param parameterIndex the parameter index 1201 * @return a {@link ResolvableType} for the specified constructor parameter 1202 * @see #forConstructorParameter(Constructor, int, Class) 1203 */ 1204 public static ResolvableType forConstructorParameter(Constructor<?> constructor, int parameterIndex) { 1205 Assert.notNull(constructor, "Constructor must not be null"); 1206 return forMethodParameter(new MethodParameter(constructor, parameterIndex)); 1207 } 1208 1209 /** 1210 * Return a {@link ResolvableType} for the specified {@link Constructor} parameter 1211 * with a given implementation. Use this variant when the class that declares the 1212 * constructor includes generic parameter variables that are satisfied by the 1213 * implementation class. 1214 * @param constructor the source constructor (must not be {@code null}) 1215 * @param parameterIndex the parameter index 1216 * @param implementationClass the implementation class 1217 * @return a {@link ResolvableType} for the specified constructor parameter 1218 * @see #forConstructorParameter(Constructor, int) 1219 */ 1220 public static ResolvableType forConstructorParameter(Constructor<?> constructor, int parameterIndex, 1221 Class<?> implementationClass) { 1222 1223 Assert.notNull(constructor, "Constructor must not be null"); 1224 MethodParameter methodParameter = new MethodParameter(constructor, parameterIndex, implementationClass); 1225 return forMethodParameter(methodParameter); 1226 } 1227 1228 /** 1229 * Return a {@link ResolvableType} for the specified {@link Method} return type. 1230 * @param method the source for the method return type 1231 * @return a {@link ResolvableType} for the specified method return 1232 * @see #forMethodReturnType(Method, Class) 1233 */ 1234 public static ResolvableType forMethodReturnType(Method method) { 1235 Assert.notNull(method, "Method must not be null"); 1236 return forMethodParameter(new MethodParameter(method, -1)); 1237 } 1238 1239 /** 1240 * Return a {@link ResolvableType} for the specified {@link Method} return type. 1241 * Use this variant when the class that declares the method includes generic 1242 * parameter variables that are satisfied by the implementation class. 1243 * @param method the source for the method return type 1244 * @param implementationClass the implementation class 1245 * @return a {@link ResolvableType} for the specified method return 1246 * @see #forMethodReturnType(Method) 1247 */ 1248 public static ResolvableType forMethodReturnType(Method method, Class<?> implementationClass) { 1249 Assert.notNull(method, "Method must not be null"); 1250 MethodParameter methodParameter = new MethodParameter(method, -1, implementationClass); 1251 return forMethodParameter(methodParameter); 1252 } 1253 1254 /** 1255 * Return a {@link ResolvableType} for the specified {@link Method} parameter. 1256 * @param method the source method (must not be {@code null}) 1257 * @param parameterIndex the parameter index 1258 * @return a {@link ResolvableType} for the specified method parameter 1259 * @see #forMethodParameter(Method, int, Class) 1260 * @see #forMethodParameter(MethodParameter) 1261 */ 1262 public static ResolvableType forMethodParameter(Method method, int parameterIndex) { 1263 Assert.notNull(method, "Method must not be null"); 1264 return forMethodParameter(new MethodParameter(method, parameterIndex)); 1265 } 1266 1267 /** 1268 * Return a {@link ResolvableType} for the specified {@link Method} parameter with a 1269 * given implementation. Use this variant when the class that declares the method 1270 * includes generic parameter variables that are satisfied by the implementation class. 1271 * @param method the source method (must not be {@code null}) 1272 * @param parameterIndex the parameter index 1273 * @param implementationClass the implementation class 1274 * @return a {@link ResolvableType} for the specified method parameter 1275 * @see #forMethodParameter(Method, int, Class) 1276 * @see #forMethodParameter(MethodParameter) 1277 */ 1278 public static ResolvableType forMethodParameter(Method method, int parameterIndex, Class<?> implementationClass) { 1279 Assert.notNull(method, "Method must not be null"); 1280 MethodParameter methodParameter = new MethodParameter(method, parameterIndex, implementationClass); 1281 return forMethodParameter(methodParameter); 1282 } 1283 1284 /** 1285 * Return a {@link ResolvableType} for the specified {@link MethodParameter}. 1286 * @param methodParameter the source method parameter (must not be {@code null}) 1287 * @return a {@link ResolvableType} for the specified method parameter 1288 * @see #forMethodParameter(Method, int) 1289 */ 1290 public static ResolvableType forMethodParameter(MethodParameter methodParameter) { 1291 return forMethodParameter(methodParameter, (Type) null); 1292 } 1293 1294 /** 1295 * Return a {@link ResolvableType} for the specified {@link MethodParameter} with a 1296 * given implementation type. Use this variant when the class that declares the method 1297 * includes generic parameter variables that are satisfied by the implementation type. 1298 * @param methodParameter the source method parameter (must not be {@code null}) 1299 * @param implementationType the implementation type 1300 * @return a {@link ResolvableType} for the specified method parameter 1301 * @see #forMethodParameter(MethodParameter) 1302 */ 1303 public static ResolvableType forMethodParameter(MethodParameter methodParameter, 1304 @Nullable ResolvableType implementationType) { 1305 1306 Assert.notNull(methodParameter, "MethodParameter must not be null"); 1307 implementationType = (implementationType != null ? implementationType : 1308 forType(methodParameter.getContainingClass())); 1309 ResolvableType owner = implementationType.as(methodParameter.getDeclaringClass()); 1310 return forType(null, new MethodParameterTypeProvider(methodParameter), owner.asVariableResolver()). 1311 getNested(methodParameter.getNestingLevel(), methodParameter.typeIndexesPerLevel); 1312 } 1313 1314 /** 1315 * Return a {@link ResolvableType} for the specified {@link MethodParameter}, 1316 * overriding the target type to resolve with a specific given type. 1317 * @param methodParameter the source method parameter (must not be {@code null}) 1318 * @param targetType the type to resolve (a part of the method parameter's type) 1319 * @return a {@link ResolvableType} for the specified method parameter 1320 * @see #forMethodParameter(Method, int) 1321 */ 1322 public static ResolvableType forMethodParameter(MethodParameter methodParameter, @Nullable Type targetType) { 1323 Assert.notNull(methodParameter, "MethodParameter must not be null"); 1324 return forMethodParameter(methodParameter, targetType, methodParameter.getNestingLevel()); 1325 } 1326 1327 /** 1328 * Return a {@link ResolvableType} for the specified {@link MethodParameter} at 1329 * a specific nesting level, overriding the target type to resolve with a specific 1330 * given type. 1331 * @param methodParameter the source method parameter (must not be {@code null}) 1332 * @param targetType the type to resolve (a part of the method parameter's type) 1333 * @param nestingLevel the nesting level to use 1334 * @return a {@link ResolvableType} for the specified method parameter 1335 * @since 5.2 1336 * @see #forMethodParameter(Method, int) 1337 */ 1338 static ResolvableType forMethodParameter( 1339 MethodParameter methodParameter, @Nullable Type targetType, int nestingLevel) { 1340 1341 ResolvableType owner = forType(methodParameter.getContainingClass()).as(methodParameter.getDeclaringClass()); 1342 return forType(targetType, new MethodParameterTypeProvider(methodParameter), owner.asVariableResolver()). 1343 getNested(nestingLevel, methodParameter.typeIndexesPerLevel); 1344 } 1345 1346 /** 1347 * Return a {@link ResolvableType} as a array of the specified {@code componentType}. 1348 * @param componentType the component type 1349 * @return a {@link ResolvableType} as an array of the specified component type 1350 */ 1351 public static ResolvableType forArrayComponent(ResolvableType componentType) { 1352 Assert.notNull(componentType, "Component type must not be null"); 1353 Class<?> arrayClass = Array.newInstance(componentType.resolve(), 0).getClass(); 1354 return new ResolvableType(arrayClass, null, null, componentType); 1355 } 1356 1357 /** 1358 * Return a {@link ResolvableType} for the specified {@link Type}. 1359 * <p>Note: The resulting {@link ResolvableType} instance may not be {@link Serializable}. 1360 * @param type the source type (potentially {@code null}) 1361 * @return a {@link ResolvableType} for the specified {@link Type} 1362 * @see #forType(Type, ResolvableType) 1363 */ 1364 public static ResolvableType forType(@Nullable Type type) { 1365 return forType(type, null, null); 1366 } 1367 1368 /** 1369 * Return a {@link ResolvableType} for the specified {@link Type} backed by the given 1370 * owner type. 1371 * <p>Note: The resulting {@link ResolvableType} instance may not be {@link Serializable}. 1372 * @param type the source type or {@code null} 1373 * @param owner the owner type used to resolve variables 1374 * @return a {@link ResolvableType} for the specified {@link Type} and owner 1375 * @see #forType(Type) 1376 */ 1377 public static ResolvableType forType(@Nullable Type type, @Nullable ResolvableType owner) { 1378 VariableResolver variableResolver = null; 1379 if (owner != null) { 1380 variableResolver = owner.asVariableResolver(); 1381 } 1382 return forType(type, variableResolver); 1383 } 1384 1385 1386 /** 1387 * Return a {@link ResolvableType} for the specified {@link ParameterizedTypeReference}. 1388 * <p>Note: The resulting {@link ResolvableType} instance may not be {@link Serializable}. 1389 * @param typeReference the reference to obtain the source type from 1390 * @return a {@link ResolvableType} for the specified {@link ParameterizedTypeReference} 1391 * @since 4.3.12 1392 * @see #forType(Type) 1393 */ 1394 public static ResolvableType forType(ParameterizedTypeReference<?> typeReference) { 1395 return forType(typeReference.getType(), null, null); 1396 } 1397 1398 /** 1399 * Return a {@link ResolvableType} for the specified {@link Type} backed by a given 1400 * {@link VariableResolver}. 1401 * @param type the source type or {@code null} 1402 * @param variableResolver the variable resolver or {@code null} 1403 * @return a {@link ResolvableType} for the specified {@link Type} and {@link VariableResolver} 1404 */ 1405 static ResolvableType forType(@Nullable Type type, @Nullable VariableResolver variableResolver) { 1406 return forType(type, null, variableResolver); 1407 } 1408 1409 /** 1410 * Return a {@link ResolvableType} for the specified {@link Type} backed by a given 1411 * {@link VariableResolver}. 1412 * @param type the source type or {@code null} 1413 * @param typeProvider the type provider or {@code null} 1414 * @param variableResolver the variable resolver or {@code null} 1415 * @return a {@link ResolvableType} for the specified {@link Type} and {@link VariableResolver} 1416 */ 1417 static ResolvableType forType( 1418 @Nullable Type type, @Nullable TypeProvider typeProvider, @Nullable VariableResolver variableResolver) { 1419 1420 if (type == null && typeProvider != null) { 1421 type = SerializableTypeWrapper.forTypeProvider(typeProvider); 1422 } 1423 if (type == null) { 1424 return NONE; 1425 } 1426 1427 // For simple Class references, build the wrapper right away - 1428 // no expensive resolution necessary, so not worth caching... 1429 if (type instanceof Class) { 1430 return new ResolvableType(type, typeProvider, variableResolver, (ResolvableType) null); 1431 } 1432 1433 // Purge empty entries on access since we don't have a clean-up thread or the like. 1434 cache.purgeUnreferencedEntries(); 1435 1436 // Check the cache - we may have a ResolvableType which has been resolved before... 1437 ResolvableType resultType = new ResolvableType(type, typeProvider, variableResolver); 1438 ResolvableType cachedType = cache.get(resultType); 1439 if (cachedType == null) { 1440 cachedType = new ResolvableType(type, typeProvider, variableResolver, resultType.hash); 1441 cache.put(cachedType, cachedType); 1442 } 1443 resultType.resolved = cachedType.resolved; 1444 return resultType; 1445 } 1446 1447 /** 1448 * Clear the internal {@code ResolvableType}/{@code SerializableTypeWrapper} cache. 1449 * @since 4.2 1450 */ 1451 public static void clearCache() { 1452 cache.clear(); 1453 SerializableTypeWrapper.cache.clear(); 1454 } 1455 1456 1457 /** 1458 * Strategy interface used to resolve {@link TypeVariable TypeVariables}. 1459 */ 1460 interface VariableResolver extends Serializable { 1461 1462 /** 1463 * Return the source of the resolver (used for hashCode and equals). 1464 */ 1465 Object getSource(); 1466 1467 /** 1468 * Resolve the specified variable. 1469 * @param variable the variable to resolve 1470 * @return the resolved variable, or {@code null} if not found 1471 */ 1472 @Nullable 1473 ResolvableType resolveVariable(TypeVariable<?> variable); 1474 } 1475 1476 1477 @SuppressWarnings("serial") 1478 private static class DefaultVariableResolver implements VariableResolver { 1479 1480 private final ResolvableType source; 1481 1482 DefaultVariableResolver(ResolvableType resolvableType) { 1483 this.source = resolvableType; 1484 } 1485 1486 @Override 1487 @Nullable 1488 public ResolvableType resolveVariable(TypeVariable<?> variable) { 1489 return this.source.resolveVariable(variable); 1490 } 1491 1492 @Override 1493 public Object getSource() { 1494 return this.source; 1495 } 1496 } 1497 1498 1499 @SuppressWarnings("serial") 1500 private static class TypeVariablesVariableResolver implements VariableResolver { 1501 1502 private final TypeVariable<?>[] variables; 1503 1504 private final ResolvableType[] generics; 1505 1506 public TypeVariablesVariableResolver(TypeVariable<?>[] variables, ResolvableType[] generics) { 1507 this.variables = variables; 1508 this.generics = generics; 1509 } 1510 1511 @Override 1512 @Nullable 1513 public ResolvableType resolveVariable(TypeVariable<?> variable) { 1514 TypeVariable<?> variableToCompare = SerializableTypeWrapper.unwrap(variable); 1515 for (int i = 0; i < this.variables.length; i++) { 1516 TypeVariable<?> resolvedVariable = SerializableTypeWrapper.unwrap(this.variables[i]); 1517 if (ObjectUtils.nullSafeEquals(resolvedVariable, variableToCompare)) { 1518 return this.generics[i]; 1519 } 1520 } 1521 return null; 1522 } 1523 1524 @Override 1525 public Object getSource() { 1526 return this.generics; 1527 } 1528 } 1529 1530 1531 private static final class SyntheticParameterizedType implements ParameterizedType, Serializable { 1532 1533 private final Type rawType; 1534 1535 private final Type[] typeArguments; 1536 1537 public SyntheticParameterizedType(Type rawType, Type[] typeArguments) { 1538 this.rawType = rawType; 1539 this.typeArguments = typeArguments; 1540 } 1541 1542 @Override 1543 public String getTypeName() { 1544 String typeName = this.rawType.getTypeName(); 1545 if (this.typeArguments.length > 0) { 1546 StringJoiner stringJoiner = new StringJoiner(", ", "<", ">"); 1547 for (Type argument : this.typeArguments) { 1548 stringJoiner.add(argument.getTypeName()); 1549 } 1550 return typeName + stringJoiner; 1551 } 1552 return typeName; 1553 } 1554 1555 @Override 1556 @Nullable 1557 public Type getOwnerType() { 1558 return null; 1559 } 1560 1561 @Override 1562 public Type getRawType() { 1563 return this.rawType; 1564 } 1565 1566 @Override 1567 public Type[] getActualTypeArguments() { 1568 return this.typeArguments; 1569 } 1570 1571 @Override 1572 public boolean equals(@Nullable Object other) { 1573 if (this == other) { 1574 return true; 1575 } 1576 if (!(other instanceof ParameterizedType)) { 1577 return false; 1578 } 1579 ParameterizedType otherType = (ParameterizedType) other; 1580 return (otherType.getOwnerType() == null && this.rawType.equals(otherType.getRawType()) && 1581 Arrays.equals(this.typeArguments, otherType.getActualTypeArguments())); 1582 } 1583 1584 @Override 1585 public int hashCode() { 1586 return (this.rawType.hashCode() * 31 + Arrays.hashCode(this.typeArguments)); 1587 } 1588 1589 @Override 1590 public String toString() { 1591 return getTypeName(); 1592 } 1593 } 1594 1595 1596 /** 1597 * Internal helper to handle bounds from {@link WildcardType WildcardTypes}. 1598 */ 1599 private static class WildcardBounds { 1600 1601 private final Kind kind; 1602 1603 private final ResolvableType[] bounds; 1604 1605 /** 1606 * Internal constructor to create a new {@link WildcardBounds} instance. 1607 * @param kind the kind of bounds 1608 * @param bounds the bounds 1609 * @see #get(ResolvableType) 1610 */ 1611 public WildcardBounds(Kind kind, ResolvableType[] bounds) { 1612 this.kind = kind; 1613 this.bounds = bounds; 1614 } 1615 1616 /** 1617 * Return {@code true} if this bounds is the same kind as the specified bounds. 1618 */ 1619 public boolean isSameKind(WildcardBounds bounds) { 1620 return this.kind == bounds.kind; 1621 } 1622 1623 /** 1624 * Return {@code true} if this bounds is assignable to all the specified types. 1625 * @param types the types to test against 1626 * @return {@code true} if this bounds is assignable to all types 1627 */ 1628 public boolean isAssignableFrom(ResolvableType... types) { 1629 for (ResolvableType bound : this.bounds) { 1630 for (ResolvableType type : types) { 1631 if (!isAssignable(bound, type)) { 1632 return false; 1633 } 1634 } 1635 } 1636 return true; 1637 } 1638 1639 private boolean isAssignable(ResolvableType source, ResolvableType from) { 1640 return (this.kind == Kind.UPPER ? source.isAssignableFrom(from) : from.isAssignableFrom(source)); 1641 } 1642 1643 /** 1644 * Return the underlying bounds. 1645 */ 1646 public ResolvableType[] getBounds() { 1647 return this.bounds; 1648 } 1649 1650 /** 1651 * Get a {@link WildcardBounds} instance for the specified type, returning 1652 * {@code null} if the specified type cannot be resolved to a {@link WildcardType}. 1653 * @param type the source type 1654 * @return a {@link WildcardBounds} instance or {@code null} 1655 */ 1656 @Nullable 1657 public static WildcardBounds get(ResolvableType type) { 1658 ResolvableType resolveToWildcard = type; 1659 while (!(resolveToWildcard.getType() instanceof WildcardType)) { 1660 if (resolveToWildcard == NONE) { 1661 return null; 1662 } 1663 resolveToWildcard = resolveToWildcard.resolveType(); 1664 } 1665 WildcardType wildcardType = (WildcardType) resolveToWildcard.type; 1666 Kind boundsType = (wildcardType.getLowerBounds().length > 0 ? Kind.LOWER : Kind.UPPER); 1667 Type[] bounds = (boundsType == Kind.UPPER ? wildcardType.getUpperBounds() : wildcardType.getLowerBounds()); 1668 ResolvableType[] resolvableBounds = new ResolvableType[bounds.length]; 1669 for (int i = 0; i < bounds.length; i++) { 1670 resolvableBounds[i] = ResolvableType.forType(bounds[i], type.variableResolver); 1671 } 1672 return new WildcardBounds(boundsType, resolvableBounds); 1673 } 1674 1675 /** 1676 * The various kinds of bounds. 1677 */ 1678 enum Kind {UPPER, LOWER} 1679 } 1680 1681 1682 /** 1683 * Internal {@link Type} used to represent an empty value. 1684 */ 1685 @SuppressWarnings("serial") 1686 static class EmptyType implements Type, Serializable { 1687 1688 static final Type INSTANCE = new EmptyType(); 1689 1690 Object readResolve() { 1691 return INSTANCE; 1692 } 1693 } 1694 1695}