03.理解java中的泛型
2017-11-20 本文已影响0人
过往入梦
- 在编程中,我们希望写出一些更加泛化的代码,通俗点举例就是说,我不关心你是什么类型,只要你能提供某种方法即可。对此,很多编程语言(譬如python和c++)提供了一种解决方案叫做
潜在类型机制
。 - java由于在1.5版本后才引入泛型,为了保证向上兼容,导致Java中的泛型并不好用。
- java的泛型是使用擦除来实现的,这是Java泛型实现的一种无奈的折中。举个栗子,List<T>,java只是在编译时候校验容器List中的数据类型T,而在实际运行时候会被
擦除
为List。也就是说,程序运行时,实际是一堆List、Map、Object等泛化的东西在运行。 - 使用JDK提供的注解
@SuppressWarnings("unchecked")
,忽略运行时的一些警告⚠️。在关闭警告时候要尽量聚焦。 - 在泛型中的所有动作发生在
边界
(对象进入和离开方法的地点)处。
使用extends
设置边界。 - 通配符?
List<? extends Fruit>
意思是具有任何从Fruit继承的类型列表,这个类型必须是明确的类型,但我们在运行中只想知道它是List<Fruit>就行了。 -
逆变
使用超类型通配符。List<? super Apple>
Apple是下界,不能向List中添加Fruit。 - 无界通配符
<?>
List<?>看起来等价于List<Object>,但List实际意思是持有任何Object类型的原生List,而List<?>实际意思是具有某种特定类型的非原生List,只是我们不知道那种类型是什么。 - 一个类不能实现同一个泛型接口的两种变体,由于擦除原因,这两个变体会成为相同的接口。
- 自限定的类型。
class SelfBounded<T extends <SelfBounded<T>>>
强制要求将正在定义的类当做参数传递给基类。 - 被称为泛型的通用语言特性的目的在于可表达性,而不仅仅是为了创建类型安全的容器。
- java中泛型的出现让数组很尴尬,我们在编程时优先选择容器而不是数组。除了效率比容器高,数组一无是处。但如果证明出切换到数组对性能提升有帮助,还是要用数组的。譬如,对于阿里巴巴的FastJson.jar里面的JSONArray,是对json中的数组的解析,但其实也可以用List解析啊,会不会有这个原因在里面,我没有想明白,后面再研究吧。