Spring强化泛型操作的工具。Class,Field,Method 都有获取 Type 的需求,但是他们获取类型的方式又不统一,回顾下JDK获取Type的方法:

    1. public class TypeTest {
    2. static class Animal<T> {
    3. public String name;
    4. public List<Pair<String, String>> propList;
    5. }
    6. static class Dog extends Animal<TypeTest> implements Serializable {
    7. private static final long serialVersionUID = 8833550896791988000L;
    8. public Dog() {
    9. }
    10. public Dog(String name) {
    11. }
    12. public Dog(List<Pair<String, String>> propList) {
    13. }
    14. public String say(List<Pair<String, String>> propList) {
    15. return "OK";
    16. }
    17. }
    18. /**
    19. * Class获取Type
    20. */
    21. @Test
    22. public void test1() {
    23. Dog dog = new Dog();
    24. System.out.println(dog.getClass().getSuperclass());
    25. System.out.println(dog.getClass().getGenericSuperclass());
    26. System.out.println(Arrays.toString(dog.getClass().getGenericInterfaces()));
    27. // class cn.lichenghao.TypeTest$Animal
    28. // cn.lichenghao.TypeTest$Animal<cn.lichenghao.TypeTest>
    29. // [interface java.io.Serializable]
    30. }
    31. /**
    32. * Field获取Type
    33. */
    34. @Test
    35. public void test2() {
    36. Dog dog = new Dog();
    37. Field[] fields = dog.getClass().getFields();
    38. for (Field field : fields) {
    39. System.out.println(field.getType() + "--" + field.getGenericType());
    40. }
    41. // class java.lang.String--class java.lang.String
    42. // interface java.util.List--java.util.List<javafx.util.Pair<java.lang.String, java.lang.String>>
    43. }
    44. /**
    45. * Method获取Type
    46. */
    47. @Test
    48. public void test3() throws NoSuchMethodException {
    49. Dog dog = new Dog();
    50. Method methodSay = dog.getClass().getMethod("say", List.class);
    51. System.out.println(Arrays.toString(methodSay.getParameterTypes()));
    52. System.out.println(Arrays.toString(methodSay.getGenericParameterTypes()));
    53. // [interface java.util.List]
    54. // [java.util.List<javafx.util.Pair<java.lang.String, java.lang.String>>]
    55. for (Constructor<?> constructor : dog.getClass().getConstructors()) {
    56. System.out.println(Arrays.toString(constructor.getGenericParameterTypes()));
    57. }
    58. // []
    59. // [java.util.List<javafx.util.Pair<java.lang.String, java.lang.String>>]
    60. // [class java.lang.String]
    61. }
    62. }

    Class、Field、Method 等都有可能获取 Type,但是每个获取的方式又不一样。Spring 中的 ResolvableType 是一个适配器,通过统一的方法规范调用来获取Type,如下演示代码所示:

    1. @Test
    2. public void test10() throws NoSuchFieldException, NoSuchMethodException {
    3. Dog dog = new Dog();
    4. // 根据实例创建 ResolvableType
    5. ResolvableType resolvableTypeDog = ResolvableType.forInstance(dog);
    6. System.out.println(resolvableTypeDog.getType());
    7. System.out.println(Arrays.toString(resolvableTypeDog.getGenerics()));
    8. // class cn.lichenghao.TypeTest$Dog
    9. // []
    10. // 根据原始类型 Class 创建 ResolvableType
    11. ResolvableType resolvableTypeClass = ResolvableType.forClass(dog.getClass());
    12. System.out.println(resolvableTypeClass.getType());
    13. System.out.println(Arrays.toString(resolvableTypeClass.getGenerics()));
    14. // class cn.lichenghao.TypeTest$Dog
    15. // []
    16. // 根据成员变量创建 ResolvableType
    17. ResolvableType resolvableTypeProp = ResolvableType.forField(dog.getClass().getField("propList"));
    18. System.out.println(resolvableTypeProp.getType());
    19. System.out.println(Arrays.toString(resolvableTypeProp.getGenerics()));
    20. // java.util.List<javafx.util.Pair<java.lang.String, java.lang.String>>
    21. // [javafx.util.Pair<java.lang.String, java.lang.String>]
    22. // 根据Method创建 ResolvableType
    23. System.out.println("根据Method创建 ResolvableType ==");
    24. MethodParameter methodParameter = MethodParameter
    25. .forParameter(dog.getClass().getMethod("say2", List.class, Map.class).getParameters()[1]);
    26. ResolvableType resolvableTypeSay =
    27. ResolvableType.forMethodParameter(methodParameter);
    28. System.out.println(resolvableTypeSay.getType());
    29. System.out.println(Arrays.toString(resolvableTypeSay.getGenerics()));
    30. // java.util.Map<java.lang.String, org.springframework.core.Ordered>
    31. // [java.lang.String, org.springframework.core.Ordered]
    32. }