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