Java--泛型--类型擦除

  1.  

     

  2.  

  3. 下限类型的泛型方法和泛型类,在编译期之后泛型类也会擦除,替换为Object类型,于无限制的泛型类和泛型方法一致

  4.  

  5.  

    package com.model.fanxing;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.util.List;
    
    /**
     * @Description:测试类
     * @Author: 张紫韩
     * @Crete 2021/7/1 17:04
     */
    public class FanXingDemo10 {
        public static void main(String[] args) {
            TestOne<Integer> testOne01 = new TestOne<>();
            TestOne<String> testOne02 = new TestOne<>();
            //不同类型的,泛型类对象,他们的Class类对象是一样的,都是由这个类对象创建的实例
            System.out.println(testOne01.getClass() == testOne02.getClass());
    
    
            //通过反射得到TestOne的Class类对象
            Class<? extends TestOne> aClass = testOne01.getClass();
    //      获取成员变量的对象
            Field[] fields = aClass.getDeclaredFields();
            for (Field f:fields){
                System.out.println(f.getName()+"\t"+f.getType().getSimpleName());
                //在编译器结束之后,会对泛类进行擦除操做,即将泛型类中的所有泛型的数据类型都编程 Object类型的数据
    //            即成员变量将不再是 Integer类型,被擦除为 Object类型了,所以所有的成员变量的 运行时数据类型为 Object类型
            }
    
            TestTwo<Number> testTwo = new TestTwo<>();
            Class<? extends TestTwo> aClass1 = testTwo.getClass();
            Field[] field = aClass1.getDeclaredFields();
            for (Field f:field){
                System.out.println(f.getName()+"\t"+f.getType().getSimpleName());
                //在编译器结束之后,会对泛类进行擦除操做,即将泛型类中的所有泛型的数据类型都编程 Object类型的数据
    //            即成员变量将不再是 Integer类型,被擦除为 Object类型了,所以所有的成员变量的 运行时数据类型为 Object类型
            }
    
            //泛型方法,T也会被替换为上限类型(List)
            TestThree<Object> testThree = new TestThree<>();
            Class<? extends TestThree> aClass2 = testThree.getClass();
            Method[] methods = aClass2.getMethods();
            for (Method m:methods){
                System.out.println(m.getName()+"\t"+m.getReturnType().getSimpleName());
            }
    
            System.out.println("------------------------------");
            Class<TestFourImpl> aClass3 = TestFourImpl.class;
            Method[] declaredMethods = aClass3.getDeclaredMethods();
            for (Method m:declaredMethods){
                System.out.println(m.getName()+"\t"+m.getReturnType().getSimpleName());
                //在接口的实现类中会有连个方法,一个是放回Integer类型的(自己写的),还有一个是为了保持接口和实现类的关系,返回值类型是Object类型
            }
    
        }
    }
    
    class TestOne<T>{
        private T name; //在编译期是T类型的数据,编译器结束会倍换成 Object类型的数据,
    
    }
    
    
    class TestTwo<T extends Number>{
        private T name; //在编译期是T类型的数据,编译器结束会倍换成 Number类型的数据,所以才能对不同类型的数据进行操做
    
    }
    
    class TestThree<T>{
        private T name;
        public static  <T extends List> T show(T t){
            return t;
        }
    
    }
    interface TestFour<T>{
        T get(T var);
    }
    class TestFourImpl implements TestFour<Integer>{
        @Override
        public Integer get(Integer var) {
            return var;
        }
    }
posted @ 2021-07-01 17:55  张紫韩  阅读(84)  评论(0编辑  收藏  举报