GenericTypeResolver returns null for entirely unresolvable type arguments only
Issue: SPR-11763
This commit is contained in:
parent
db5d651057
commit
bea34ea41c
|
@ -243,10 +243,10 @@ public abstract class GenericTypeResolver {
|
|||
*/
|
||||
public static Class<?>[] resolveTypeArguments(Class<?> clazz, Class<?> genericIfc) {
|
||||
ResolvableType type = ResolvableType.forClass(clazz).as(genericIfc);
|
||||
if (!type.hasGenerics() || type.hasUnresolvableGenerics()) {
|
||||
if (!type.hasGenerics() || type.isEntirelyUnresolvable()) {
|
||||
return null;
|
||||
}
|
||||
return type.resolveGenerics();
|
||||
return type.resolveGenerics(Object.class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -416,7 +416,24 @@ public final class ResolvableType implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Determine whether the underlying type has unresolvable generics:
|
||||
* Return {@code true} if this type contains unresolvable generics only,
|
||||
* that is, no substitute for any of its declared type variables.
|
||||
*/
|
||||
boolean isEntirelyUnresolvable() {
|
||||
if (this == NONE) {
|
||||
return false;
|
||||
}
|
||||
ResolvableType[] generics = getGenerics();
|
||||
for (ResolvableType generic : generics) {
|
||||
if (!generic.isUnresolvableTypeVariable() && !generic.isWildcardWithoutBounds()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the underlying type has any unresolvable generics:
|
||||
* either through an unresolvable type variable on the type itself
|
||||
* or through implementing a generic interface in a raw fashion,
|
||||
* i.e. without substituting that interface's type variables.
|
||||
|
@ -634,8 +651,8 @@ public final class ResolvableType implements Serializable {
|
|||
/**
|
||||
* Convenience method that will {@link #getGeneric(int...) get} and
|
||||
* {@link #resolve() resolve} a specific generic parameters.
|
||||
* @param indexes the indexes that refer to the generic parameter (may be omitted to
|
||||
* return the first generic)
|
||||
* @param indexes the indexes that refer to the generic parameter
|
||||
* (may be omitted to return the first generic)
|
||||
* @return a resolved {@link Class} or {@code null}
|
||||
* @see #getGeneric(int...)
|
||||
* @see #resolve()
|
||||
|
@ -645,11 +662,11 @@ public final class ResolvableType implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Resolve this type to a {@link java.lang.Class}, returning {@code null} if the type
|
||||
* cannot be resolved. This method will consider bounds of {@link TypeVariable}s and
|
||||
* {@link WildcardType}s if direct resolution fails; however, bounds of
|
||||
* {@code Object.class} will be ignored.
|
||||
* @return the resolved {@link Class} or {@code null}
|
||||
* Resolve this type to a {@link java.lang.Class}, returning {@code null}
|
||||
* if the type cannot be resolved. This method will consider bounds of
|
||||
* {@link TypeVariable}s and {@link WildcardType}s if direct resolution fails;
|
||||
* however, bounds of {@code Object.class} will be ignored.
|
||||
* @return the resolved {@link Class}, or {@code null} if not resolvable
|
||||
* @see #resolve(Class)
|
||||
* @see #resolveGeneric(int...)
|
||||
* @see #resolveGenerics()
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package org.springframework.core;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
|
@ -166,11 +167,21 @@ public class GenericTypeResolverTests {
|
|||
public void getGenericsOnArrayFromReturnCannotBeResolved() throws Exception {
|
||||
// SPR-11044
|
||||
Class<?> resolved = GenericTypeResolver.resolveReturnType(
|
||||
WithArrayBase.class.getDeclaredMethod("array", Object[].class),
|
||||
WithArray.class);
|
||||
WithArrayBase.class.getDeclaredMethod("array", Object[].class), WithArray.class);
|
||||
assertThat(resolved, equalTo((Class) Object[].class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveIncompleteTypeVariables() {
|
||||
// SPR-11763
|
||||
Class<?>[] resolved = GenericTypeResolver.resolveTypeArguments(IdFixingRepository.class, Repository.class);
|
||||
assertNotNull(resolved);
|
||||
assertEquals(2, resolved.length);
|
||||
assertEquals(Object.class, resolved[0]);
|
||||
assertEquals(Long.class, resolved[1]);
|
||||
}
|
||||
|
||||
|
||||
public interface MyInterfaceType<T> {
|
||||
}
|
||||
|
||||
|
@ -314,4 +325,10 @@ public class GenericTypeResolverTests {
|
|||
static abstract class WithArray<T> extends WithArrayBase<T> {
|
||||
}
|
||||
|
||||
interface Repository<T, ID extends Serializable> {
|
||||
}
|
||||
|
||||
interface IdFixingRepository<T> extends Repository<T, Long> {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue