Polishing

This commit is contained in:
Juergen Hoeller
2023-10-24 22:53:44 +02:00
parent 09aa59f9e7
commit 925fa0272b
6 changed files with 135 additions and 127 deletions

View File

@@ -1000,18 +1000,20 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
*/
protected abstract static class PropertyHandler {
@Nullable
private final Class<?> propertyType;
private final boolean readable;
private final boolean writable;
public PropertyHandler(Class<?> propertyType, boolean readable, boolean writable) {
public PropertyHandler(@Nullable Class<?> propertyType, boolean readable, boolean writable) {
this.propertyType = propertyType;
this.readable = readable;
this.writable = writable;
}
@Nullable
public Class<?> getPropertyType() {
return this.propertyType;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -129,7 +129,6 @@ public class DirectFieldAccessor extends AbstractNestablePropertyAccessor {
ReflectionUtils.makeAccessible(this.field);
return this.field.get(getWrappedInstance());
}
catch (IllegalAccessException ex) {
throw new InvalidPropertyException(getWrappedClass(),
this.field.getName(), "Field is not accessible", ex);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,6 +36,10 @@ public abstract class AbstractApplicationEventListenerTests {
}
}
protected <T> GenericTestEvent<T> createGenericTestEvent(T payload) {
return new GenericTestEvent<>(this, payload);
}
protected static class GenericTestEvent<T> extends ApplicationEvent {
@@ -51,6 +55,7 @@ public abstract class AbstractApplicationEventListenerTests {
}
}
protected static class SmartGenericTestEvent<T> extends GenericTestEvent<T> implements ResolvableTypeProvider {
private final ResolvableType resolvableType;
@@ -67,6 +72,7 @@ public abstract class AbstractApplicationEventListenerTests {
}
}
protected static class StringEvent extends GenericTestEvent<String> {
public StringEvent(Object source, String payload) {
@@ -74,6 +80,7 @@ public abstract class AbstractApplicationEventListenerTests {
}
}
protected static class LongEvent extends GenericTestEvent<Long> {
public LongEvent(Object source, Long payload) {
@@ -81,31 +88,31 @@ public abstract class AbstractApplicationEventListenerTests {
}
}
protected <T> GenericTestEvent<T> createGenericTestEvent(T payload) {
return new GenericTestEvent<>(this, payload);
}
static class GenericEventListener implements ApplicationListener<GenericTestEvent<?>> {
@Override
public void onApplicationEvent(GenericTestEvent<?> event) {
}
}
static class ObjectEventListener implements ApplicationListener<GenericTestEvent<Object>> {
@Override
public void onApplicationEvent(GenericTestEvent<Object> event) {
}
}
static class UpperBoundEventListener
implements ApplicationListener<GenericTestEvent<? extends RuntimeException>> {
static class UpperBoundEventListener implements ApplicationListener<GenericTestEvent<? extends RuntimeException>> {
@Override
public void onApplicationEvent(GenericTestEvent<? extends RuntimeException> event) {
}
}
static class StringEventListener implements ApplicationListener<GenericTestEvent<String>> {
@Override
@@ -113,6 +120,7 @@ public abstract class AbstractApplicationEventListenerTests {
}
}
@SuppressWarnings("rawtypes")
static class RawApplicationListener implements ApplicationListener {
@@ -121,10 +129,10 @@ public abstract class AbstractApplicationEventListenerTests {
}
}
static class TestEvents {
public GenericTestEvent<?> wildcardEvent;
}
}

View File

@@ -104,7 +104,8 @@ public class GenericApplicationListenerAdapterTests extends AbstractApplicationE
@Test
public void genericListenerStrictTypeSubClass() {
supportsEventType(false, ObjectEventListener.class, ResolvableType.forClassWithGenerics(GenericTestEvent.class, Long.class));
supportsEventType(false, ObjectEventListener.class,
ResolvableType.forClassWithGenerics(GenericTestEvent.class, Long.class));
}
@Test

View File

@@ -138,7 +138,7 @@ public class ResolvableType implements Serializable {
/**
* Private constructor used to create a new {@link ResolvableType} for cache key purposes,
* Private constructor used to create a new {@code ResolvableType} for cache key purposes,
* with no upfront resolution.
*/
private ResolvableType(
@@ -153,7 +153,7 @@ public class ResolvableType implements Serializable {
}
/**
* Private constructor used to create a new {@link ResolvableType} for cache value purposes,
* Private constructor used to create a new {@code ResolvableType} for cache value purposes,
* with upfront resolution and a pre-calculated hash.
* @since 4.2
*/
@@ -169,7 +169,7 @@ public class ResolvableType implements Serializable {
}
/**
* Private constructor used to create a new {@link ResolvableType} for uncached purposes,
* Private constructor used to create a new {@code ResolvableType} for uncached purposes,
* with upfront resolution but lazily calculated hash.
*/
private ResolvableType(Type type, @Nullable TypeProvider typeProvider,
@@ -184,7 +184,7 @@ public class ResolvableType implements Serializable {
}
/**
* Private constructor used to create a new {@link ResolvableType} on a {@link Class} basis.
* Private constructor used to create a new {@code ResolvableType} on a {@link Class} basis.
* <p>Avoids all {@code instanceof} checks in order to create a straight {@link Class} wrapper.
* @since 4.2
*/
@@ -223,7 +223,7 @@ public class ResolvableType implements Serializable {
/**
* Return the underlying source of the resolvable type. Will return a {@link Field},
* {@link MethodParameter} or {@link Type} depending on how the {@link ResolvableType}
* {@link MethodParameter} or {@link Type} depending on how the {@code ResolvableType}
* was constructed. This method is primarily to provide access to additional type
* information or meta-data that alternative JVM languages may provide.
*/
@@ -340,13 +340,14 @@ public class ResolvableType implements Serializable {
}
}
if (ourResolved == null) {
ourResolved = resolve(Object.class);
ourResolved = toClass();
}
Class<?> otherResolved = other.toClass();
// We need an exact type match for generics
// List<CharSequence> is not assignable from List<String>
if (exactMatch ? !ourResolved.equals(otherResolved) : !ClassUtils.isAssignable(ourResolved, otherResolved)) {
if (exactMatch ? !ourResolved.equals(otherResolved) :
!ClassUtils.isAssignable(ourResolved, otherResolved)) {
return false;
}
@@ -357,13 +358,15 @@ public class ResolvableType implements Serializable {
if (ourGenerics.length != typeGenerics.length) {
return false;
}
if (matchedBefore == null) {
matchedBefore = new IdentityHashMap<>(1);
}
matchedBefore.put(this.type, other.type);
for (int i = 0; i < ourGenerics.length; i++) {
if (!ourGenerics[i].isAssignableFrom(typeGenerics[i], matchedBefore)) {
return false;
if (ourGenerics.length > 0) {
if (matchedBefore == null) {
matchedBefore = new IdentityHashMap<>(1);
}
matchedBefore.put(this.type, other.type);
for (int i = 0; i < ourGenerics.length; i++) {
if (!ourGenerics[i].isAssignableFrom(typeGenerics[i], matchedBefore)) {
return false;
}
}
}
}
@@ -428,12 +431,12 @@ public class ResolvableType implements Serializable {
}
/**
* Return this type as a {@link ResolvableType} of the specified class. Searches
* Return this type as a {@code ResolvableType} of the specified class. Searches
* {@link #getSuperType() supertype} and {@link #getInterfaces() interface}
* hierarchies to find a match, returning {@link #NONE} if this type does not
* implement or extend the specified class.
* @param type the required type (typically narrowed)
* @return a {@link ResolvableType} representing this object as the specified
* @return a {@code ResolvableType} representing this object as the specified
* type, or {@link #NONE} if not resolvable as that type
* @see #asCollection()
* @see #asMap()
@@ -458,9 +461,9 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} representing the direct supertype of this type.
* Return a {@code ResolvableType} representing the direct supertype of this type.
* <p>If no supertype is available this method returns {@link #NONE}.
* <p>Note: The resulting {@link ResolvableType} instance may not be {@link Serializable}.
* <p>Note: The resulting {@code ResolvableType} instance may not be {@link Serializable}.
* @see #getInterfaces()
*/
public ResolvableType getSuperType() {
@@ -487,10 +490,10 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} array representing the direct interfaces
* Return a {@code ResolvableType} array representing the direct interfaces
* implemented by this type. If this type does not implement any interfaces an
* empty array is returned.
* <p>Note: The resulting {@link ResolvableType} instances may not be {@link Serializable}.
* <p>Note: The resulting {@code ResolvableType} instances may not be {@link Serializable}.
* @see #getSuperType()
*/
public ResolvableType[] getInterfaces() {
@@ -618,17 +621,17 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} for the specified nesting level.
* Return a {@code ResolvableType} for the specified nesting level.
* <p>See {@link #getNested(int, Map)} for details.
* @param nestingLevel the nesting level
* @return the {@link ResolvableType} type, or {@code #NONE}
* @return the {@code ResolvableType} type, or {@code #NONE}
*/
public ResolvableType getNested(int nestingLevel) {
return getNested(nestingLevel, null);
}
/**
* Return a {@link ResolvableType} for the specified nesting level.
* Return a {@code ResolvableType} for the specified nesting level.
* <p>The nesting level refers to the specific generic parameter that should be returned.
* A nesting level of 1 indicates this type; 2 indicates the first nested generic;
* 3 the second; and so on. For example, given {@code List<Set<Integer>>} level 1 refers
@@ -645,7 +648,7 @@ public class ResolvableType implements Serializable {
* current type, 2 for the first nested generic, 3 for the second and so on
* @param typeIndexesPerLevel a map containing the generic index for a given
* nesting level (may be {@code null})
* @return a {@link ResolvableType} for the nested level, or {@link #NONE}
* @return a {@code ResolvableType} for the nested level, or {@link #NONE}
*/
public ResolvableType getNested(int nestingLevel, @Nullable Map<Integer, Integer> typeIndexesPerLevel) {
ResolvableType result = this;
@@ -667,7 +670,7 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} representing the generic parameter for the
* Return a {@code ResolvableType} representing the generic parameter for the
* given indexes. Indexes are zero based; for example given the type
* {@code Map<Integer, List<String>>}, {@code getGeneric(0)} will access the
* {@code Integer}. Nested generics can be accessed by specifying multiple indexes;
@@ -677,7 +680,7 @@ public class ResolvableType implements Serializable {
* <p>If no generic is available at the specified indexes {@link #NONE} is returned.
* @param indexes the indexes that refer to the generic parameter
* (may be omitted to return the first generic)
* @return a {@link ResolvableType} for the specified generic, or {@link #NONE}
* @return a {@code ResolvableType} for the specified generic, or {@link #NONE}
* @see #hasGenerics()
* @see #getGenerics()
* @see #resolveGeneric(int...)
@@ -700,12 +703,12 @@ public class ResolvableType implements Serializable {
}
/**
* Return an array of {@link ResolvableType ResolvableTypes} representing the generic parameters of
* Return an array of {@code ResolvableType ResolvableTypes} representing the generic parameters of
* this type. If no generics are available an empty array is returned. If you need to
* access a specific generic consider using the {@link #getGeneric(int...)} method as
* it allows access to nested generics and protects against
* {@code IndexOutOfBoundsExceptions}.
* @return an array of {@link ResolvableType ResolvableTypes} representing the generic parameters
* @return an array of {@code ResolvableType ResolvableTypes} representing the generic parameters
* (never {@code null})
* @see #hasGenerics()
* @see #getGeneric(int...)
@@ -839,7 +842,7 @@ public class ResolvableType implements Serializable {
/**
* Resolve this type by a single level, returning the resolved value or {@link #NONE}.
* <p>Note: The returned {@link ResolvableType} should only be used as an intermediary
* <p>Note: The returned {@code ResolvableType} should only be used as an intermediary
* as it cannot be serialized.
*/
ResolvableType resolveType() {
@@ -958,7 +961,7 @@ public class ResolvableType implements Serializable {
}
/**
* Adapts this {@link ResolvableType} to a {@link VariableResolver}.
* Adapts this {@code ResolvableType} to a {@link VariableResolver}.
*/
@Nullable
VariableResolver asVariableResolver() {
@@ -1004,12 +1007,12 @@ public class ResolvableType implements Serializable {
// Factory methods
/**
* Return a {@link ResolvableType} for the specified {@link Class},
* Return a {@code ResolvableType} for the specified {@link Class},
* using the full generic type information for assignability checks.
* <p>For example: {@code ResolvableType.forClass(MyArrayList.class)}.
* @param clazz the class to introspect ({@code null} is semantically
* equivalent to {@code Object.class} for typical use cases here)
* @return a {@link ResolvableType} for the specified class
* @return a {@code ResolvableType} for the specified class
* @see #forClass(Class, Class)
* @see #forClassWithGenerics(Class, Class...)
*/
@@ -1018,13 +1021,13 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} for the specified {@link Class},
* Return a {@code ResolvableType} for the specified {@link Class},
* doing assignability checks against the raw class only (analogous to
* {@link Class#isAssignableFrom}, which this serves as a wrapper for).
* <p>For example: {@code ResolvableType.forRawClass(List.class)}.
* @param clazz the class to introspect ({@code null} is semantically
* equivalent to {@code Object.class} for typical use cases here)
* @return a {@link ResolvableType} for the specified class
* @return a {@code ResolvableType} for the specified class
* @since 4.2
* @see #forClass(Class)
* @see #getRawClass()
@@ -1048,12 +1051,12 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} for the specified base type
* Return a {@code ResolvableType} for the specified base type
* (interface or base class) with a given implementation class.
* <p>For example: {@code ResolvableType.forClass(List.class, MyArrayList.class)}.
* @param baseType the base type (must not be {@code null})
* @param implementationClass the implementation class
* @return a {@link ResolvableType} for the specified base type backed by the
* @return a {@code ResolvableType} for the specified base type backed by the
* given implementation class
* @see #forClass(Class)
* @see #forClassWithGenerics(Class, Class...)
@@ -1065,10 +1068,10 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} for the specified {@link Class} with pre-declared generics.
* Return a {@code ResolvableType} for the specified {@link Class} with pre-declared generics.
* @param clazz the class (or interface) to introspect
* @param generics the generics of the class
* @return a {@link ResolvableType} for the specific class and generics
* @return a {@code ResolvableType} for the specific class and generics
* @see #forClassWithGenerics(Class, ResolvableType...)
*/
public static ResolvableType forClassWithGenerics(Class<?> clazz, Class<?>... generics) {
@@ -1082,10 +1085,10 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} for the specified {@link Class} with pre-declared generics.
* Return a {@code ResolvableType} for the specified {@link Class} with pre-declared generics.
* @param clazz the class (or interface) to introspect
* @param generics the generics of the class
* @return a {@link ResolvableType} for the specific class and generics
* @return a {@code ResolvableType} for the specific class and generics
* @see #forClassWithGenerics(Class, Class...)
*/
public static ResolvableType forClassWithGenerics(Class<?> clazz, ResolvableType... generics) {
@@ -1106,12 +1109,12 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} for the specified instance. The instance does not
* Return a {@code ResolvableType} for the specified instance. The instance does not
* convey generic information but if it implements {@link ResolvableTypeProvider} a
* more precise {@link ResolvableType} can be used than the simple one based on
* more precise {@code ResolvableType} can be used than the simple one based on
* the {@link #forClass(Class) Class instance}.
* @param instance the instance (possibly {@code null})
* @return a {@link ResolvableType} for the specified instance,
* @return a {@code ResolvableType} for the specified instance,
* or {@code NONE} for {@code null}
* @since 4.2
* @see ResolvableTypeProvider
@@ -1127,9 +1130,9 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} for the specified {@link Field}.
* Return a {@code ResolvableType} for the specified {@link Field}.
* @param field the source field
* @return a {@link ResolvableType} for the specified field
* @return a {@code ResolvableType} for the specified field
* @see #forField(Field, Class)
*/
public static ResolvableType forField(Field field) {
@@ -1138,13 +1141,13 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} for the specified {@link Field} with a given
* Return a {@code ResolvableType} for the specified {@link Field} with a given
* implementation.
* <p>Use this variant when the class that declares the field includes generic
* parameter variables that are satisfied by the implementation class.
* @param field the source field
* @param implementationClass the implementation class
* @return a {@link ResolvableType} for the specified field
* @return a {@code ResolvableType} for the specified field
* @see #forField(Field)
*/
public static ResolvableType forField(Field field, Class<?> implementationClass) {
@@ -1154,13 +1157,13 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} for the specified {@link Field} with a given
* Return a {@code ResolvableType} for the specified {@link Field} with a given
* implementation.
* <p>Use this variant when the class that declares the field includes generic
* parameter variables that are satisfied by the implementation type.
* @param field the source field
* @param implementationType the implementation type
* @return a {@link ResolvableType} for the specified field
* @return a {@code ResolvableType} for the specified field
* @see #forField(Field)
*/
public static ResolvableType forField(Field field, @Nullable ResolvableType implementationType) {
@@ -1171,7 +1174,7 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} for the specified {@link Field} with the
* Return a {@code ResolvableType} for the specified {@link Field} with the
* given nesting level.
* @param field the source field
* @param nestingLevel the nesting level (1 for the outer level; 2 for a nested
@@ -1184,7 +1187,7 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} for the specified {@link Field} with a given
* Return a {@code ResolvableType} for the specified {@link Field} with a given
* implementation and the given nesting level.
* <p>Use this variant when the class that declares the field includes generic
* parameter variables that are satisfied by the implementation class.
@@ -1192,7 +1195,7 @@ public class ResolvableType implements Serializable {
* @param nestingLevel the nesting level (1 for the outer level; 2 for a nested
* generic type; etc)
* @param implementationClass the implementation class
* @return a {@link ResolvableType} for the specified field
* @return a {@code ResolvableType} for the specified field
* @see #forField(Field)
*/
public static ResolvableType forField(Field field, int nestingLevel, @Nullable Class<?> implementationClass) {
@@ -1202,10 +1205,10 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} for the specified {@link Constructor} parameter.
* Return a {@code ResolvableType} for the specified {@link Constructor} parameter.
* @param constructor the source constructor (must not be {@code null})
* @param parameterIndex the parameter index
* @return a {@link ResolvableType} for the specified constructor parameter
* @return a {@code ResolvableType} for the specified constructor parameter
* @see #forConstructorParameter(Constructor, int, Class)
*/
public static ResolvableType forConstructorParameter(Constructor<?> constructor, int parameterIndex) {
@@ -1214,14 +1217,14 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} for the specified {@link Constructor} parameter
* Return a {@code ResolvableType} for the specified {@link Constructor} parameter
* with a given implementation. Use this variant when the class that declares the
* constructor includes generic parameter variables that are satisfied by the
* implementation class.
* @param constructor the source constructor (must not be {@code null})
* @param parameterIndex the parameter index
* @param implementationClass the implementation class
* @return a {@link ResolvableType} for the specified constructor parameter
* @return a {@code ResolvableType} for the specified constructor parameter
* @see #forConstructorParameter(Constructor, int)
*/
public static ResolvableType forConstructorParameter(Constructor<?> constructor, int parameterIndex,
@@ -1233,9 +1236,9 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} for the specified {@link Method} return type.
* Return a {@code ResolvableType} for the specified {@link Method} return type.
* @param method the source for the method return type
* @return a {@link ResolvableType} for the specified method return
* @return a {@code ResolvableType} for the specified method return
* @see #forMethodReturnType(Method, Class)
*/
public static ResolvableType forMethodReturnType(Method method) {
@@ -1244,12 +1247,12 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} for the specified {@link Method} return type.
* Return a {@code ResolvableType} for the specified {@link Method} return type.
* <p>Use this variant when the class that declares the method includes generic
* parameter variables that are satisfied by the implementation class.
* @param method the source for the method return type
* @param implementationClass the implementation class
* @return a {@link ResolvableType} for the specified method return
* @return a {@code ResolvableType} for the specified method return
* @see #forMethodReturnType(Method)
*/
public static ResolvableType forMethodReturnType(Method method, Class<?> implementationClass) {
@@ -1259,10 +1262,10 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} for the specified {@link Method} parameter.
* Return a {@code ResolvableType} for the specified {@link Method} parameter.
* @param method the source method (must not be {@code null})
* @param parameterIndex the parameter index
* @return a {@link ResolvableType} for the specified method parameter
* @return a {@code ResolvableType} for the specified method parameter
* @see #forMethodParameter(Method, int, Class)
* @see #forMethodParameter(MethodParameter)
*/
@@ -1272,13 +1275,13 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} for the specified {@link Method} parameter with a
* Return a {@code ResolvableType} for the specified {@link Method} parameter with a
* given implementation. Use this variant when the class that declares the method
* includes generic parameter variables that are satisfied by the implementation class.
* @param method the source method (must not be {@code null})
* @param parameterIndex the parameter index
* @param implementationClass the implementation class
* @return a {@link ResolvableType} for the specified method parameter
* @return a {@code ResolvableType} for the specified method parameter
* @see #forMethodParameter(Method, int, Class)
* @see #forMethodParameter(MethodParameter)
*/
@@ -1289,9 +1292,9 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} for the specified {@link MethodParameter}.
* Return a {@code ResolvableType} for the specified {@link MethodParameter}.
* @param methodParameter the source method parameter (must not be {@code null})
* @return a {@link ResolvableType} for the specified method parameter
* @return a {@code ResolvableType} for the specified method parameter
* @see #forMethodParameter(Method, int)
*/
public static ResolvableType forMethodParameter(MethodParameter methodParameter) {
@@ -1299,12 +1302,12 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} for the specified {@link MethodParameter} with a
* Return a {@code ResolvableType} for the specified {@link MethodParameter} with a
* given implementation type. Use this variant when the class that declares the method
* includes generic parameter variables that are satisfied by the implementation type.
* @param methodParameter the source method parameter (must not be {@code null})
* @param implementationType the implementation type
* @return a {@link ResolvableType} for the specified method parameter
* @return a {@code ResolvableType} for the specified method parameter
* @see #forMethodParameter(MethodParameter)
*/
public static ResolvableType forMethodParameter(MethodParameter methodParameter,
@@ -1319,11 +1322,11 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} for the specified {@link MethodParameter},
* Return a {@code ResolvableType} for the specified {@link MethodParameter},
* overriding the target type to resolve with a specific given type.
* @param methodParameter the source method parameter (must not be {@code null})
* @param targetType the type to resolve (a part of the method parameter's type)
* @return a {@link ResolvableType} for the specified method parameter
* @return a {@code ResolvableType} for the specified method parameter
* @see #forMethodParameter(Method, int)
*/
public static ResolvableType forMethodParameter(MethodParameter methodParameter, @Nullable Type targetType) {
@@ -1332,13 +1335,13 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} for the specified {@link MethodParameter} at
* Return a {@code ResolvableType} for the specified {@link MethodParameter} at
* a specific nesting level, overriding the target type to resolve with a specific
* given type.
* @param methodParameter the source method parameter (must not be {@code null})
* @param targetType the type to resolve (a part of the method parameter's type)
* @param nestingLevel the nesting level to use
* @return a {@link ResolvableType} for the specified method parameter
* @return a {@code ResolvableType} for the specified method parameter
* @since 5.2
* @see #forMethodParameter(Method, int)
*/
@@ -1351,9 +1354,9 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} as an array of the specified {@code componentType}.
* Return a {@code ResolvableType} as an array of the specified {@code componentType}.
* @param componentType the component type
* @return a {@link ResolvableType} as an array of the specified component type
* @return a {@code ResolvableType} as an array of the specified component type
*/
public static ResolvableType forArrayComponent(ResolvableType componentType) {
Assert.notNull(componentType, "Component type must not be null");
@@ -1362,10 +1365,10 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} for the specified {@link Type}.
* <p>Note: The resulting {@link ResolvableType} instance may not be {@link Serializable}.
* Return a {@code ResolvableType} for the specified {@link Type}.
* <p>Note: The resulting {@code ResolvableType} instance may not be {@link Serializable}.
* @param type the source type (potentially {@code null})
* @return a {@link ResolvableType} for the specified {@link Type}
* @return a {@code ResolvableType} for the specified {@link Type}
* @see #forType(Type, ResolvableType)
*/
public static ResolvableType forType(@Nullable Type type) {
@@ -1373,12 +1376,12 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} for the specified {@link Type} backed by the given
* Return a {@code ResolvableType} for the specified {@link Type} backed by the given
* owner type.
* <p>Note: The resulting {@link ResolvableType} instance may not be {@link Serializable}.
* <p>Note: The resulting {@code ResolvableType} instance may not be {@link Serializable}.
* @param type the source type or {@code null}
* @param owner the owner type used to resolve variables
* @return a {@link ResolvableType} for the specified {@link Type} and owner
* @return a {@code ResolvableType} for the specified {@link Type} and owner
* @see #forType(Type)
*/
public static ResolvableType forType(@Nullable Type type, @Nullable ResolvableType owner) {
@@ -1391,10 +1394,10 @@ public class ResolvableType implements Serializable {
/**
* Return a {@link ResolvableType} for the specified {@link ParameterizedTypeReference}.
* <p>Note: The resulting {@link ResolvableType} instance may not be {@link Serializable}.
* Return a {@code ResolvableType} for the specified {@link ParameterizedTypeReference}.
* <p>Note: The resulting {@code ResolvableType} instance may not be {@link Serializable}.
* @param typeReference the reference to obtain the source type from
* @return a {@link ResolvableType} for the specified {@link ParameterizedTypeReference}
* @return a {@code ResolvableType} for the specified {@link ParameterizedTypeReference}
* @since 4.3.12
* @see #forType(Type)
*/
@@ -1403,23 +1406,23 @@ public class ResolvableType implements Serializable {
}
/**
* Return a {@link ResolvableType} for the specified {@link Type} backed by a given
* Return a {@code ResolvableType} for the specified {@link Type} backed by a given
* {@link VariableResolver}.
* @param type the source type or {@code null}
* @param variableResolver the variable resolver or {@code null}
* @return a {@link ResolvableType} for the specified {@link Type} and {@link VariableResolver}
* @return a {@code ResolvableType} for the specified {@link Type} and {@link VariableResolver}
*/
static ResolvableType forType(@Nullable Type type, @Nullable VariableResolver variableResolver) {
return forType(type, null, variableResolver);
}
/**
* Return a {@link ResolvableType} for the specified {@link Type} backed by a given
* Return a {@code ResolvableType} for the specified {@link Type} backed by a given
* {@link VariableResolver}.
* @param type the source type or {@code null}
* @param typeProvider the type provider or {@code null}
* @param variableResolver the variable resolver or {@code null}
* @return a {@link ResolvableType} for the specified {@link Type} and {@link VariableResolver}
* @return a {@code ResolvableType} for the specified {@link Type} and {@link VariableResolver}
*/
static ResolvableType forType(
@Nullable Type type, @Nullable TypeProvider typeProvider, @Nullable VariableResolver variableResolver) {

View File

@@ -200,8 +200,8 @@ class ResolvableTypeTests {
@Test
void forFieldMustNotBeNull() throws Exception {
assertThatIllegalArgumentException()
.isThrownBy(() -> ResolvableType.forField(null))
.withMessage("Field must not be null");
.isThrownBy(() -> ResolvableType.forField(null))
.withMessage("Field must not be null");
}
@Test
@@ -214,8 +214,8 @@ class ResolvableTypeTests {
@Test
void forConstructorParameterMustNotBeNull() throws Exception {
assertThatIllegalArgumentException()
.isThrownBy(() -> ResolvableType.forConstructorParameter(null, 0))
.withMessage("Constructor must not be null");
.isThrownBy(() -> ResolvableType.forConstructorParameter(null, 0))
.withMessage("Constructor must not be null");
}
@Test
@@ -228,8 +228,8 @@ class ResolvableTypeTests {
@Test
void forMethodParameterByIndexMustNotBeNull() throws Exception {
assertThatIllegalArgumentException()
.isThrownBy(() -> ResolvableType.forMethodParameter(null, 0))
.withMessage("Method must not be null");
.isThrownBy(() -> ResolvableType.forMethodParameter(null, 0))
.withMessage("Method must not be null");
}
@Test
@@ -268,8 +268,8 @@ class ResolvableTypeTests {
@Test
void forMethodParameterMustNotBeNull() throws Exception {
assertThatIllegalArgumentException()
.isThrownBy(() -> ResolvableType.forMethodParameter(null))
.withMessage("MethodParameter must not be null");
.isThrownBy(() -> ResolvableType.forMethodParameter(null))
.withMessage("MethodParameter must not be null");
}
@Test // SPR-16210
@@ -295,8 +295,8 @@ class ResolvableTypeTests {
@Test
void forMethodReturnMustNotBeNull() throws Exception {
assertThatIllegalArgumentException()
.isThrownBy(() -> ResolvableType.forMethodReturnType(null))
.withMessage("Method must not be null");
.isThrownBy(() -> ResolvableType.forMethodReturnType(null))
.withMessage("Method must not be null");
}
@Test
@@ -343,7 +343,7 @@ class ResolvableTypeTests {
ResolvableType type = ResolvableType.forField(field);
assertThat(type.isArray()).isTrue();
assertThat(type.getComponentType().getType())
.isEqualTo(((Class) field.getGenericType()).getComponentType());
.isEqualTo(((Class) field.getGenericType()).getComponentType());
}
@Test
@@ -686,7 +686,6 @@ class ResolvableTypeTests {
assertThat(type.resolve()).isEqualTo(CharSequence.class);
}
@Test
void resolveBoundedTypeVariableWildcardResult() throws Exception {
ResolvableType type = ResolvableType.forMethodReturnType(Methods.class.getMethod("boundedTypeVariableWildcardResult"));
@@ -701,30 +700,26 @@ class ResolvableTypeTests {
@Test
void resolveTypeVariableFromSimpleInterfaceType() {
ResolvableType type = ResolvableType.forClass(
MySimpleInterfaceType.class).as(MyInterfaceType.class);
ResolvableType type = ResolvableType.forClass(MySimpleInterfaceType.class).as(MyInterfaceType.class);
assertThat(type.resolveGeneric()).isEqualTo(String.class);
}
@Test
void resolveTypeVariableFromSimpleCollectionInterfaceType() {
ResolvableType type = ResolvableType.forClass(
MyCollectionInterfaceType.class).as(MyInterfaceType.class);
ResolvableType type = ResolvableType.forClass(MyCollectionInterfaceType.class).as(MyInterfaceType.class);
assertThat(type.resolveGeneric()).isEqualTo(Collection.class);
assertThat(type.resolveGeneric(0, 0)).isEqualTo(String.class);
}
@Test
void resolveTypeVariableFromSimpleSuperclassType() {
ResolvableType type = ResolvableType.forClass(
MySimpleSuperclassType.class).as(MySuperclassType.class);
ResolvableType type = ResolvableType.forClass(MySimpleSuperclassType.class).as(MySuperclassType.class);
assertThat(type.resolveGeneric()).isEqualTo(String.class);
}
@Test
void resolveTypeVariableFromSimpleCollectionSuperclassType() {
ResolvableType type = ResolvableType.forClass(
MyCollectionSuperclassType.class).as(MySuperclassType.class);
ResolvableType type = ResolvableType.forClass(MyCollectionSuperclassType.class).as(MySuperclassType.class);
assertThat(type.resolveGeneric()).isEqualTo(Collection.class);
assertThat(type.resolveGeneric(0, 0)).isEqualTo(String.class);
}
@@ -751,8 +746,7 @@ class ResolvableTypeTests {
void resolveTypeVariableFromSuperType() throws Exception {
ResolvableType type = ResolvableType.forClass(ExtendsList.class);
assertThat(type.resolve()).isEqualTo(ExtendsList.class);
assertThat(type.asCollection().resolveGeneric())
.isEqualTo(CharSequence.class);
assertThat(type.asCollection().resolveGeneric()).isEqualTo(CharSequence.class);
}
@Test
@@ -964,8 +958,8 @@ class ResolvableTypeTests {
@Test
void isAssignableFromMustNotBeNull() throws Exception {
assertThatIllegalArgumentException()
.isThrownBy(() -> ResolvableType.forClass(Object.class).isAssignableFrom((ResolvableType) null))
.withMessage("ResolvableType must not be null");
.isThrownBy(() -> ResolvableType.forClass(Object.class).isAssignableFrom((ResolvableType) null))
.withMessage("ResolvableType must not be null");
}
@Test
@@ -1004,6 +998,7 @@ class ResolvableTypeTests {
void isAssignableFromCannotBeResolved() throws Exception {
ResolvableType objectType = ResolvableType.forClass(Object.class);
ResolvableType unresolvableVariable = ResolvableType.forField(AssignmentBase.class.getField("o"));
assertThat(unresolvableVariable.resolve()).isNull();
assertThatResolvableType(objectType).isAssignableFrom(unresolvableVariable);
assertThatResolvableType(unresolvableVariable).isAssignableFrom(objectType);
@@ -1220,9 +1215,9 @@ class ResolvableTypeTests {
@Test
void forClassWithMismatchedGenerics() throws Exception {
assertThatIllegalArgumentException()
.isThrownBy(() -> ResolvableType.forClassWithGenerics(Map.class, Integer.class))
.withMessageContaining("Mismatched number of generics specified for")
.withMessageContaining("java.util.Map<K,V>");
.isThrownBy(() -> ResolvableType.forClassWithGenerics(Map.class, Integer.class))
.withMessageContaining("Mismatched number of generics specified for")
.withMessageContaining("java.util.Map<K,V>");
}
@Test
@@ -1277,7 +1272,7 @@ class ResolvableTypeTests {
}
@Test
void hasUnresolvableGenericsWhenImplementesRawInterface() throws Exception {
void hasUnresolvableGenericsWhenImplementingRawInterface() throws Exception {
ResolvableType type = ResolvableType.forClass(MySimpleInterfaceTypeWithImplementsRaw.class);
for (ResolvableType generic : type.getGenerics()) {
assertThat(generic.resolve()).isNotNull();