Convenient forType methods for ParameterizedTypeReference
Issue: SPR-16054
This commit is contained in:
parent
d4677be5c0
commit
53091c76bf
|
|
@ -53,6 +53,10 @@ public abstract class ParameterizedTypeReference<T> {
|
||||||
this.type = parameterizedType.getActualTypeArguments()[0];
|
this.type = parameterizedType.getActualTypeArguments()[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ParameterizedTypeReference(Type type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public Type getType() {
|
public Type getType() {
|
||||||
return this.type;
|
return this.type;
|
||||||
|
|
@ -75,6 +79,19 @@ public abstract class ParameterizedTypeReference<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a {@code ParameterizedTypeReference} wrapping the given type.
|
||||||
|
* @param type a generic type (possibly obtained via reflection,
|
||||||
|
* e.g. from {@link java.lang.reflect.Method#getGenericReturnType()})
|
||||||
|
* @return a corresponding reference which may be passed into
|
||||||
|
* {@code ParameterizedTypeReference}-accepting methods
|
||||||
|
* @since 4.3.12
|
||||||
|
*/
|
||||||
|
public static <T> ParameterizedTypeReference<T> forType(Type type) {
|
||||||
|
return new ParameterizedTypeReference<T>(type) {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private static Class<?> findParameterizedTypeReferenceSubclass(Class<?> child) {
|
private static Class<?> findParameterizedTypeReferenceSubclass(Class<?> child) {
|
||||||
Class<?> parent = child.getSuperclass();
|
Class<?> parent = child.getSuperclass();
|
||||||
if (Object.class == parent) {
|
if (Object.class == parent) {
|
||||||
|
|
|
||||||
|
|
@ -1340,6 +1340,19 @@ public class ResolvableType implements Serializable {
|
||||||
return forType(type, variableResolver);
|
return forType(type, variableResolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a {@link ResolvableType} for the specified {@link ParameterizedTypeReference}.
|
||||||
|
* Note: The resulting {@link ResolvableType} may not be {@link Serializable}.
|
||||||
|
* @param typeReference the reference to obtain the source type from
|
||||||
|
* @return a {@link ResolvableType} for the specified {@link ParameterizedTypeReference}
|
||||||
|
* @since 4.3.12
|
||||||
|
* @see #forType(Type)
|
||||||
|
*/
|
||||||
|
public static ResolvableType forType(ParameterizedTypeReference<?> typeReference) {
|
||||||
|
return forType(typeReference.getType(), null ,null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a {@link ResolvableType} for the specified {@link Type} backed by a given
|
* Return a {@link ResolvableType} for the specified {@link Type} backed by a given
|
||||||
* {@link VariableResolver}.
|
* {@link VariableResolver}.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2013 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -33,25 +33,40 @@ import static org.junit.Assert.*;
|
||||||
public class ParameterizedTypeReferenceTests {
|
public class ParameterizedTypeReferenceTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void map() throws NoSuchMethodException {
|
public void stringTypeReference() {
|
||||||
Type mapType = getClass().getMethod("mapMethod").getGenericReturnType();
|
|
||||||
ParameterizedTypeReference<Map<Object,String>> mapTypeReference = new ParameterizedTypeReference<Map<Object,String>>() {};
|
|
||||||
assertEquals(mapType, mapTypeReference.getType());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void list() throws NoSuchMethodException {
|
|
||||||
Type mapType = getClass().getMethod("listMethod").getGenericReturnType();
|
|
||||||
ParameterizedTypeReference<List<String>> mapTypeReference = new ParameterizedTypeReference<List<String>>() {};
|
|
||||||
assertEquals(mapType, mapTypeReference.getType());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void string() {
|
|
||||||
ParameterizedTypeReference<String> typeReference = new ParameterizedTypeReference<String>() {};
|
ParameterizedTypeReference<String> typeReference = new ParameterizedTypeReference<String>() {};
|
||||||
assertEquals(String.class, typeReference.getType());
|
assertEquals(String.class, typeReference.getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mapTypeReference() throws Exception {
|
||||||
|
Type mapType = getClass().getMethod("mapMethod").getGenericReturnType();
|
||||||
|
ParameterizedTypeReference<Map<Object,String>> typeReference = new ParameterizedTypeReference<Map<Object,String>>() {};
|
||||||
|
assertEquals(mapType, typeReference.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void listTypeReference() throws Exception {
|
||||||
|
Type listType = getClass().getMethod("listMethod").getGenericReturnType();
|
||||||
|
ParameterizedTypeReference<List<String>> typeReference = new ParameterizedTypeReference<List<String>>() {};
|
||||||
|
assertEquals(listType, typeReference.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void reflectiveTypeReferenceWithSpecificDeclaration() throws Exception{
|
||||||
|
Type listType = getClass().getMethod("listMethod").getGenericReturnType();
|
||||||
|
ParameterizedTypeReference<List<String>> typeReference = ParameterizedTypeReference.forType(listType);
|
||||||
|
assertEquals(listType, typeReference.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void reflectiveTypeReferenceWithGenericDeclaration() throws Exception{
|
||||||
|
Type listType = getClass().getMethod("listMethod").getGenericReturnType();
|
||||||
|
ParameterizedTypeReference<?> typeReference = ParameterizedTypeReference.forType(listType);
|
||||||
|
assertEquals(listType, typeReference.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Map<Object, String> mapMethod() {
|
public static Map<Object, String> mapMethod() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -870,6 +870,22 @@ public class ResolvableTypeTests {
|
||||||
assertThat(this.typeVariableCaptor.getValue().getName(), equalTo("T"));
|
assertThat(this.typeVariableCaptor.getValue().getName(), equalTo("T"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void resolveTypeVariableFromReflectiveParameterizedTypeReference() throws Exception {
|
||||||
|
Type sourceType = Methods.class.getMethod("typedReturn").getGenericReturnType();
|
||||||
|
ResolvableType type = ResolvableType.forType(ParameterizedTypeReference.forType(sourceType));
|
||||||
|
assertThat(type.resolve(), nullValue());
|
||||||
|
assertThat(type.getType().toString(), equalTo("T"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void resolveTypeVariableFromDeclaredParameterizedTypeReference() throws Exception {
|
||||||
|
Type sourceType = Methods.class.getMethod("charSequenceReturn").getGenericReturnType();
|
||||||
|
ResolvableType reflectiveType = ResolvableType.forType(sourceType);
|
||||||
|
ResolvableType declaredType = ResolvableType.forType(new ParameterizedTypeReference<List<CharSequence>>() {});
|
||||||
|
assertEquals(reflectiveType, declaredType);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void toStrings() throws Exception {
|
public void toStrings() throws Exception {
|
||||||
assertThat(ResolvableType.NONE.toString(), equalTo("?"));
|
assertThat(ResolvableType.NONE.toString(), equalTo("?"));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue