Java泛型

2020-06-06  本文已影响0人  simonenfp

泛型定义

Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数,就是将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型(类型实参)。

假定我们有这样一个需求:写一个排序方法,能够对整型数组、字符串数组甚至其他任何类型的数组进行排序,该如何实现?

答案是可以使用 Java 泛型

使用 Java 泛型的概念,我们可以写一个泛型方法来对一个对象数组排序。然后,调用该泛型方法来对整型数组、浮点数数组、字符串数组等进行排序。

泛型原理:

泛型是java5才引入的,虚拟机其实并不支持泛型,为了向下兼容,Java在编译期间擦除了所有的泛型信息,这样Java就不需要产生新的类型到字节码,所有的泛型类型最终都是一种原始类型,在Java运行时根本就不存在泛型信息。

编译器如何擦除泛型:

限定通配符(为了更灵活的转型):

图6 如上图6 ,编译器报错,无法add,因为<? extends Animal>是限定animals这个引用类型范围是Animals或者其子类,只是代表这个范围,并不是具体某个引用类型,所以没法与任何类型匹配,add任何都报错(除了null),但是get是可以的,他一定是Animal的子类,只要用其父类接收就可以。 图7.png 如上图7,因为<? extends Animal>是限定animals引用类型范围是Animal或者它的父类(并非代表其指向的具体ArrayList对象存放的是Animal或者其父类),所以animals可以add任何Animal子类以及Animal,因为这些一定是这个引用类型的子类;也可以get,但是只能用Object接收,否则如上编译器报错,因此get没什么意义。

这时候可以看一下Collections集合类的copy泛型方法:
public static <T> void copy(List<? super T> dest, List<? extends T> src)
可以看到src参数使用了上界通配符,dest参数使用了下界通配符,意味着src引用所指向的列表一定是T或者T的某个子类型,而dest引用范围是T或者它的父类,所以将src中的元素复制到dest一定是可以的,所以保证了从src复制到dest的类型正确性。

非限定通配符:

如List<?>,既不能读也不能写,等价于List<? extends Object>,对于List<?>编译器会进行安全检查,而List不会。

上一篇 下一篇

猜你喜欢

热点阅读