Spring强化泛型操作的工具。Class,Field,Method 都有获取 Type 的需求,但是他们获取类型的方式又不统一,回顾下JDK获取Type的方法:
public class TypeTest {
static class Animal<T> {
public String name;
public List<Pair<String, String>> propList;
}
static class Dog extends Animal<TypeTest> implements Serializable {
private static final long serialVersionUID = 8833550896791988000L;
public Dog() {
}
public Dog(String name) {
}
public Dog(List<Pair<String, String>> propList) {
}
public String say(List<Pair<String, String>> propList) {
return "OK";
}
}
/**
* Class获取Type
*/
@Test
public void test1() {
Dog dog = new Dog();
System.out.println(dog.getClass().getSuperclass());
System.out.println(dog.getClass().getGenericSuperclass());
System.out.println(Arrays.toString(dog.getClass().getGenericInterfaces()));
// class cn.lichenghao.TypeTest$Animal
// cn.lichenghao.TypeTest$Animal<cn.lichenghao.TypeTest>
// [interface java.io.Serializable]
}
/**
* Field获取Type
*/
@Test
public void test2() {
Dog dog = new Dog();
Field[] fields = dog.getClass().getFields();
for (Field field : fields) {
System.out.println(field.getType() + "--" + field.getGenericType());
}
// class java.lang.String--class java.lang.String
// interface java.util.List--java.util.List<javafx.util.Pair<java.lang.String, java.lang.String>>
}
/**
* Method获取Type
*/
@Test
public void test3() throws NoSuchMethodException {
Dog dog = new Dog();
Method methodSay = dog.getClass().getMethod("say", List.class);
System.out.println(Arrays.toString(methodSay.getParameterTypes()));
System.out.println(Arrays.toString(methodSay.getGenericParameterTypes()));
// [interface java.util.List]
// [java.util.List<javafx.util.Pair<java.lang.String, java.lang.String>>]
for (Constructor<?> constructor : dog.getClass().getConstructors()) {
System.out.println(Arrays.toString(constructor.getGenericParameterTypes()));
}
// []
// [java.util.List<javafx.util.Pair<java.lang.String, java.lang.String>>]
// [class java.lang.String]
}
}
Class、Field、Method 等都有可能获取 Type,但是每个获取的方式又不一样。Spring 中的 ResolvableType 是一个适配器,通过统一的方法规范调用来获取Type,如下演示代码所示:
@Test
public void test10() throws NoSuchFieldException, NoSuchMethodException {
Dog dog = new Dog();
// 根据实例创建 ResolvableType
ResolvableType resolvableTypeDog = ResolvableType.forInstance(dog);
System.out.println(resolvableTypeDog.getType());
System.out.println(Arrays.toString(resolvableTypeDog.getGenerics()));
// class cn.lichenghao.TypeTest$Dog
// []
// 根据原始类型 Class 创建 ResolvableType
ResolvableType resolvableTypeClass = ResolvableType.forClass(dog.getClass());
System.out.println(resolvableTypeClass.getType());
System.out.println(Arrays.toString(resolvableTypeClass.getGenerics()));
// class cn.lichenghao.TypeTest$Dog
// []
// 根据成员变量创建 ResolvableType
ResolvableType resolvableTypeProp = ResolvableType.forField(dog.getClass().getField("propList"));
System.out.println(resolvableTypeProp.getType());
System.out.println(Arrays.toString(resolvableTypeProp.getGenerics()));
// java.util.List<javafx.util.Pair<java.lang.String, java.lang.String>>
// [javafx.util.Pair<java.lang.String, java.lang.String>]
// 根据Method创建 ResolvableType
System.out.println("根据Method创建 ResolvableType ==");
MethodParameter methodParameter = MethodParameter
.forParameter(dog.getClass().getMethod("say2", List.class, Map.class).getParameters()[1]);
ResolvableType resolvableTypeSay =
ResolvableType.forMethodParameter(methodParameter);
System.out.println(resolvableTypeSay.getType());
System.out.println(Arrays.toString(resolvableTypeSay.getGenerics()));
// java.util.Map<java.lang.String, org.springframework.core.Ordered>
// [java.lang.String, org.springframework.core.Ordered]
}