java-Type的获取方式

https://www.jianshu.com/p/ac1b6dd211d0
这篇介绍了Type的分类,通常我们需要通过Class的类型或者变量的类型来获取Type

下面我们来看几个例子

1 通过Class获取Type

其本身就是一个Type类型
还有2个方法
getSuperclass和getGenericSuperclass,
如果是泛型类的话,2者会有区别,否则是一致的.
如果要获取参数化类型的话Class的getGenericSuperclass方法用的场景会比较多

参考:https://www.cnblogs.com/maokun/p/6773203.html

public class TypeTest {

    class Person<T> {
    }

    class Student extends Person<TypeTest> {
    }

    @Test
    public void test1()
    {
        System.out.println("Student.class.getSuperclass()\t"
                + Student.class.getSuperclass());
        System.out.println("Student.class.getGenericSuperclass()\t"
                + Student.class.getGenericSuperclass());

        System.out.println("Test.class.getSuperclass()\t"
                + TypeTest.class.getSuperclass());
        System.out.println("Test.class.getGenericSuperclass()\t"
                + TypeTest.class.getGenericSuperclass());

        System.out.println("Object.class.getGenericSuperclass()\t"
                + Object.class.getGenericSuperclass());
        System.out.println("Object.class.getSuperclass()\t"
                + Object.class.getSuperclass());

        System.out.println("void.class.getSuperclass()\t"
                + void.class.getSuperclass());
        System.out.println("void.class.getGenericSuperclass()\t"
                + void.class.getGenericSuperclass());

        System.out.println("int[].class.getSuperclass()\t"
                + int[].class.getSuperclass());
        System.out.println("int[].class.getGenericSuperclass()\t"
                + int[].class.getGenericSuperclass());
    }
}

结果输出:

Student.class.getSuperclass()   class demo.base.reflect.type.TypeTest$Person
Student.class.getGenericSuperclass()    demo.base.reflect.type.TypeTest.demo.base.reflect.type.TypeTest$Person<demo.base.reflect.type.TypeTest>
Test.class.getSuperclass()  class java.lang.Object
Test.class.getGenericSuperclass()   class java.lang.Object
Object.class.getGenericSuperclass() null
Object.class.getSuperclass()    null
void.class.getSuperclass()  null
void.class.getGenericSuperclass()   null
int[].class.getSuperclass() class java.lang.Object
int[].class.getGenericSuperclass()  class java.lang.Object

2 通过Field获取Type

getType和getGenericType方法

public class FieldTest {


    class Person<T> {

        public List<CharSequence> charSequenceList;

        public String str;
    }

    class Student extends Person<FieldTest> {


    }

    @Test
    public void test1() throws NoSuchFieldException {

        {
            Field field=Student.class.getField("str");
            System.out.println(field.getType());
            System.out.println(field.getGenericType());
        }

        {
            Field field=Student.class.getField("charSequenceList");
            System.out.println(field.getType());
            System.out.println(field.getGenericType());
        }
    }
}

输出:

class java.lang.String
class java.lang.String
interface java.util.List
java.util.List<java.lang.CharSequence>

3 通过Method获取参数Type

Method是获取其参数或者返回值的Type,还有一个特殊的构造函数也可以归类为Method

public class MethodTest {


    static class Person<T> {
        
    }

    static class Student extends Person<MethodTest> {


        public Student(List<CharSequence> list)
        {

        }

        public Integer test(List<CharSequence> list)
        {
            return null;
        }

    }

    @Test
    public void test1() throws NoSuchMethodException {

        {
            Method method=Student.class.getMethod("test",List.class);

            Class type1=method.getParameterTypes()[0];
            Type type2=method.getGenericParameterTypes()[0];

            System.out.println(type1);
            System.out.println(type2);
        }

        {
            Constructor constructor=Student.class.getConstructor(List.class);

            Class type1=constructor.getParameterTypes()[0];
            Type type2=constructor.getGenericParameterTypes()[0];
            System.out.println(type1);
            System.out.println(type2);
        }
    }
}

4 MethodParameter

Spring对方法的参数做了一个抽象封装,如参数和返回值都可以认为是一个MethodParameter
可以使用MethodParameter.forMethodOrConstructor静态方法来构建一个MethodParameter

public class MethodParameterTests {

    public static class TestItem
    {
        public TestItem(List<String> list)
        {

        }

        public void m1(List<Integer> intParam)
        {

        }
    }

    @Test
    public void test() throws NoSuchMethodException {

        {
            Method method=TestItem.class.getMethod("m1",List.class);
            MethodParameter parameter=MethodParameter.forMethodOrConstructor(method,0);
            System.out.println(parameter.getParameterType());
            System.out.println(parameter.getGenericParameterType());
        }

        {
            Constructor constructor=TestItem.class.getConstructor(List.class);
            MethodParameter parameter=MethodParameter.forMethodOrConstructor(constructor,0);
            System.out.println(parameter.getParameterType());
            System.out.println(parameter.getGenericParameterType());
        }
    }
}

通过以上,已经了解到获取Type的几种场景

  1. Class
  2. Field字段
  3. Method参数
  4. Constructor参数

总结一下:需求是要获取Type和GenericType,但每个对象获取方法并不一致,怎么办?
需要做一个适配器,Spring中的ResolvableType就是来解决这个问题的.
ResolvableType可以传入上面任何参数,然后定义了公共的方法来统一方法规范调用,简化了获取Type的成本

比如MethodParameter已经对Method和Constructor做了一个整合,ResolvableType则对上面整体都做了一个整合

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容