众妙之门

业精于勤,荒于嬉;行成于思,毁于随

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

1、泛型概念的提出
Java语言类型包括八种基本类型(byte short int long float double boolean char)和复杂类型,复杂类型包括类和数组。

早期Java版本(1.4之前)如果要代指某个泛化类对象,只能使用Object,这样写出来的代码需要增加强转,而且缺少类型检查,代码缺少健壮性。在1.5之后,Java引入了泛型(Generic)的概念,提供了一套抽象的类型表示方法。利用泛型,我们可以:

  • 1、表示多个可变类型之间的相互关系:HashMap<T,S>表示类型T与S的映射,HashMap<T, S extends T>表示T的子类与T的映射关系
  • 2、细化类的能力:ArrayList<T> 可以容纳任何指定类型T的数据,当T代指人,则是人的有序列表,当T代指杯子,则是杯子的有序列表,所有对象个体可以共用相同的操作行为
  • 3、复杂类型被细分成更多类型:List<People>和List<Cup>是两种不同的类型,这意味着List<People> listP = new ArrayList<Cup>()是不可编译的。后面会提到,这种检查基于编译而非运行,所以说是不可编译并非不可运行,因为运行时ArrayList不保留Cup信息。另外要注意,即使People继承自Object,List<Object> listO = new ArrayList<People>()也是不可编译的,应理解为两种不同类型。因为listO可以容纳任意类型,而实例化的People列表只能接收People实例,这会破坏数据类型完整性。

java泛型是在编译期有效,在运行期被删除,也就是说所有的泛型参数类型在编译后都会被清除掉。结论已经说明了,下面看一个方法重载的例子。

泛型使用一个问题,先定义一个接口

public interface TestA<T extends Map> {
    void methodA(List<T> list);
}

然后编写实现

public class TestB implements TestA {
    public void methodA(List<HashMap> list) {
        System.out.println("methodA");
    }
}

咋眼一看没得什么问题,实际在编译的时候会报错

'methodA(List<HashMap>)' in 'TestB' clashes with 'methodA(List<T>)' in 'TestA'; both methods have same erasure, yet neither overrides the other

这个错误的意思是,两个方法在类型擦除后,具有相同的原生类型参数列表,但是也不能覆盖另一个方法。

泛型类型在编译后,会做类型擦除,只剩下原生类型。如参数列表中的T类型会编译成List

如果修改为

public class TestB implements TestA {
    public void methodA(List list) {
        System.out.println("methodA");
    }
}

这样的实现就不会报错。

转换的规则如下:

  • List<HashMap>,List<LinkedHashMap>,List<T>擦除后的类型为List
  • List<HashMap>[]擦除后的类型为List[]
  • List<? extends E>,List< ? super E>擦除后的类型为List<E>
  • List<T extends Serializable&Cloneable>擦除后为List<Serializable>

Java编译后的字节码中已经没有泛型的任何信息了,也就说一个泛型类和一个普通类在经过编译后都指向了同一字节码,比如 MyMethod<T>类,经过编译后将只有一份MyMethod.class类。

不管是 MyMethod<String>还是MyMethod<Integer>引用的都是同一个字节码,Java之所以这样处理有两方面原因:

  • 避免JVM大换血.C++的泛型生命期延续到了运行期,而Java是在编译器擦除掉的,如果JVM也把泛型类型延续到运行期,那么JVM就需要进行大量的重构工作了.
  • 版本兼容,在 编译期擦除可以更好的支持原生类型RawType,在Java1.5或1.6平台上,即使声明一个List这样的原生类型也是可以正常编译通过的,只是会产生警告信息而已.
posted on 2019-12-23 10:38  xuanm  阅读(442)  评论(0编辑  收藏  举报