自学内容网 自学内容网

【泛型】学习笔记

1.工作中的使用

例子1
    @Getter
    private int type;
    private Class<? extends AbstractActivity> clazz;

    ActivityType(int type, Class<? extends AbstractActivity> clazz) {
        this.type = type;
        this.clazz = clazz;
    }
    

    public AbstractActivity newInstance(ActivityEntity activityEntity) {
        try {
            // 创建一个对象,并且传入一个参数
            return clazz.getConstructor(ActivityEntity.class).newInstance(activityEntity);
        } catch (Exception e) {
            logger.error("ActivityType newInstance catch error:", e);
            return null;
        }
    }

例子2
    public static <T> T f(Class<T> clazz, int num) throws Exception {
        // 使用时,我们要知道调用的类型是啥,进行指定即可,int.class其实我们可以用限定符指定
        return clazz.getConstructor(int.class).newInstance(num);
    }

   Integer num = f(int.class, 3);
   System.out.println(num);

2.guava TypeToken

Guava的TypeToken在泛型编程中的应用_guava typetoken-CSDN博客

3.Fastjson的使用 // 指定TypeToken防止解析出的类型变为了Object

public static void main(String ... args) {
        String personString = "[{\"id\":1,\"name\":\"Irene\",\"password\":\"123456\"},{\"id\":2,\"name\":\"Aiden\","
            + "\"password\":\"123456\"}]";

        List<Person> persons = JSON.parseObject(personString, new TypeToken<List<Person>>(){}.getType());
    }

    @Data
    public static class Person {
        private int id;
        private String name;
        private String password;
    }

4.黑马学习笔记

/*
1)没有泛型时:
    没有泛型前: 使用Object可以存放任意的元素
    泛型的出现:和集合有很大的关系

    需要强转
    使用上:读取时是Object,具体使用需要强转。
    严重问题:虽然类型转换有错误,但是编译期没问题,运行期异常。

2)引入泛型
    作用:编译器的检查。 在使用时必须按照指定的类型来存储。

3)泛型的好处:
    1.编译期检查类型
    2.无需数据类型转换

4)
    会自动装箱(添加时)。
    会自动拆箱(从集合取出数据时)。


5)泛型集合
    有点像:类型的形参。

6)泛型的本质:就是参数化类型。类型的形参。

7)泛型标识: T,E,K,V

8)泛型类没有指定类型,则按照Object。

9)泛型类,不支持int,编译期的时候,转化为Object,因为int不继承Object,因此不能是基本数据类型!

10)打印xx.getClass():
    同一个泛型类,根据不同的数据类型创建的对象,本质是同一类型。

11)泛型在逻辑上可以看成是不同的类型,但是实际上都是相同的类型,也就是Xxx.class

12)泛型类继承:
    子类有泛型的话,必须有一个类型和父类提供的一样,当然自己可以新增别的泛型类型。
    子类无泛型的话,则必须明确父类的泛型类型。

13)泛型接口
    实现类不是泛型类
    实现类是泛型类

14)泛型方法
    泛型方法:在调用方法的时候,指明泛型的具体类型。
       注意:
        只使用了泛型类中的类型的方法不是泛型方法,而是成员方法。
        泛型方法是独立于泛型类中的类型的,可以加static。 成员方法类型使用的是类中指定的泛型,不能加static。

    泛型类则是:在实例化的时候指明泛型的具体类型。

15)类型通配符
    上限:
        ? : 表示实参,但是我们可以指定边界,比如: <? extends Number>, 就是:Number或者Number的子类。

        问题: 不能填充元素。因为我们不知道它到底是什么类型,所以我们不能new一个元素填充进去。

    下限:
        <? super 实参类型>

16)泛型擦除:
    1.5版本才引入的,之前没有泛型,为了和之前代码兼容,泛型只存在于编译阶段,在进入jvm之前,与泛型相关的信息会被擦除掉。

    证明:
        intList.getClass().getSimpleName();
        strList.getClass().getSimpleName();
        打印信息:发现都是ArrayList

17)拿到字节码文件
    Class<? extends Erasure> clazz = erasure.getClass();

    获取到所有的成员变量:
        Field[] fields : clazz.getDeclaredFields();

        field.getType().getSimpleName() 发现 是Object // 也就是通过反射再去看的时候,类型被擦除成了Object

    有限制的类型擦除:T extens Number,就会被擦除为Number

    桥接方法的生成:
        类型擦除和多态发生了冲突,为了解决这个问题,编译器会产生一个桥接方法,在虚拟机中会由参数好返回值类型不同而产生2个不同的字节码文件,
            但是虚拟机能够正确的处理这种情况。
        info:Integer
        info:Object

18)泛型数组
    可以声明带泛型的数组引用,但是不能直接创建带泛型的数组对象。
    可以通过:Array.newInstance(Class<T>, int)创建T[]数组

    在编译期会进行类型擦除,而数组则是一直持有,所以2者设计是冲突的,java这直接不让那么做。

    创建:
        T[] arr = new T[3]; // 直接失败,因为我们根本不知道T是什么类型。


        @SuppressWarnings("all")
        public static <T> T[] createArr(Class<T> clazz, int len) {
            return (T[]) Array.newInstance(clazz, len);
        }

19)泛型和反射
    Class<Person> personClass = Person.class;
    Constructor<Person> constructor = personClass.getConstructor();
    Person person = constructor.newInstance();
 */


原文地址:https://blog.csdn.net/themagickeyjianan/article/details/140385452

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!