泛型的深入学习,带你了解什么泛型到底是怎么实现的

一、泛型的简单使用

    1、泛型怎么使用

    在编写代码的过程中,有的时候,使用泛型类,但有时候忘了(偷懒)没有指定其泛型,很多时候其实并不会报错,但在运行调用指定方法的时候,就会出问题。泛型能够提高自身代码的清晰度,在后期维护代码,他人调用接口的时候,就能方便的识别出泛型类的参数。类型变量使用大写形式,且比较短, 这是很常见的。在 Java 库中, 使用变量 E 表示集合的元素类型, K 和 V 分别表示表的关键字与值的类型。T ( 需要时还可以用临近的字母 U 和 S ) 表示“ 任意类型”。

    2、泛型的类型限制

    不能确定泛型对象含有相应的方法,因此可以通过extends对其进行限定,规定其只能实现了Demo2方法,这里extends不是继承的extends,只是限定的意思,T可以是Demo2的子类,也可以是实现类,还有Demo2本身限定可以有多个,但只能有一个类(多个接口),但类必须放在第一位。

二、泛型知识进阶

    1、泛型和虚拟机

    在虚拟机中没有相应的泛型对象,虚拟机中只有普通的类,所有的类都会进行泛型类型擦除,转化成普通类。

    2、泛型类型擦除

    原始类型的名字就是删去类型参数后的泛型类型名。擦除( erased) 类型变量 , 并替换为限定类型 (无限定的变量用 Object) ,如图:


    原始类型用第一个限定的类型变量来替换,如图


    但是,有时候你会遇到这样的问题,如图


   在本例中,在子类DateInterval有函数void setSecond(LocalDate second)方法,父类Pair中擦除了泛型后,有函数void setSecond(Object second)方法,这两个方法不是同一个方法,不会覆盖,因此,按照常理来说,在DateInterval也会继承参数为Object的方法,这样就会有一个问题,在多态的情况下如下代码


DateInterval interval= new DateInterval();

Pair<LocalDate> pair=interval;

pair.setSecond(aDate);


    在Pair中不存在setSecond(LocalDate second)方法,因此只能调用Object参数的方法,但Object的方法没有被重写过,就只能调用Pair中的Object方法,这样泛型和多态就冲突了,为了解决这个冲突,编译器会在DateInterval类中生成桥方法public void setSecond(Object second){setSecond(setSecond((Date) second)}该方法覆盖了父类的方法,在调用的时候,会调用该方法调用了LocalDate方法,这样逻辑就走通了

泛型无法实例化类型变量

public Pair() { first = new T(); second = new T(); }//无法使用

应该要这样使用,如图,在Pair创建一个构造器表达式。


    在这里使用了Supplier是函数式接口,有一个get函数,其返回泛型参数T。makePair方法中调用了Pair的有参构造器,实现了泛型的(实例化)。还有一点,在静态方法中,无法使用类的泛型参数,要使用需要自定义泛型参数。

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