知道什么是绝望么,就是一遍又一遍的体会痛苦。知道什么是希望么,就是在一遍一遍的痛苦中醒来。
全军出击!
是不是看着标题挺吓唬人,其实吧,这就是一篇笔记的整理,配图都没有,纯文字,保证正确使用,后期会及时贴补一些图片的。
Java中有泛型,Kotlin也有,毕竟都是JVM平台的苗,怎能不遵守规则。有些人看到泛型挺晕乎,我也是,用了不少次泛型,始终没有一个具体的了解,这个笔记作为二次学习后的记忆加深,同时分享给有困难需要解决问题、很想了解学习泛型的同学。
不废话,直接进入正题:
JVM平台泛型特点
- 属于编译期泛型,也可以叫做伪泛型。在编译期间存在类型约束,而运行期间则遵循JVM的实现方式(类型擦除),将类型全部擦除为Object
- 泛型具有通配符,可在一定程度上保证特定环境的数据安全
- 型变包括点型变和声明处型变
Java && Kotlin一些特点
一.型变
Java:型变包括三种:不变、协变、逆变,如下所示:
ArrayList<Integer> listExtends = new ArrayList<Integer>();//不变
ArrayList<? extends Number> listExtends = new ArrayList<Integer>();//协变
ArrayList<? super Integer> listSuper = new ArrayList<Object>();//逆变
Java的协变使用 ? extends T 表示,协变的泛型不能存只能取。协变具有类型上界,在编译期间无法保证存入的对象能够转换成已知的上界。但取出时可明确知道所有对象均是上界的子类,可以顺利转换成上界类型。
Java的逆变使用 ? super T 表示,逆变的泛型能存不能取。逆变具有类型下界,编译期间可以正确存入下界类型,编译器明确知道可以正确将该类型转换为其父类类型。但取出时编译器不知晓确切的存入类型,为了避免转换异常,故只能取出为Object。
Java只支持点型变,即方法和变量中的泛型参数可以接受T或其子父类的类型
具体参见:http://www.cnblogs.com/chyu/p/4630798.html
Kotlin:型变包括三种:不变、协变、逆变,如下所示:
Class A <T>
Class A <out T>
Class A <in T>
Kotlin支持的型变和Java类似,只是使用了不同的修饰符,并且相较于Java来讲,更加严格和安全。同时,对于支持协变、逆变的泛型类,Kotlin定义它们互为子父类,可以互相转换,而这在Java中是不支持的。
Kotlin支持声明处型变和点型变,声明点型变指类、接口支持泛型T的子或父类型,点型变指的是方法和变量中的泛型参数可以接受T或其子父类的类型
Kotlin官网中文版:http://www.kotlincn.net/docs/reference/generics.html
Kotlin中文网博客:https://blog.kotliner.cn/2017/06/26/kotlin-generics/
二、Java与Kotlin泛型型变的对应关系
Java | Kotlin | 特点 |
---|---|---|
T | T | 可读又可写 |
? extends T | out T | 可读不可写 |
? super T | in T | 可写不可读 |
三、通配符 ? 和 *
在Java和Kotlin中均支持通配符,该无界通配符表明泛型T可以接受任意类型的引用,但会存在一些内容限制,具体如表格所示。
Java | 泛型类型 | 特点 |
---|---|---|
? | T | 可读不可写,返回Object |
? | ? extends T | 可读不可写,返回Object |
? | ? super T | 不支持 |
Kotlin | 泛型类型 | 特点 |
---|---|---|
* | T | 可读不可写,返回T |
* | out T | 可读不可写,返回T |
* | in T | 不可写不可读(逆变本身不可读取) |
Kotlin中文网博客:https://blog.kotliner.cn/2017/06/26/kotlin-generics/
以上就是本期所有内容,能力有限,如果纰漏,欢迎同学积极指正,我定当及时改正。感谢网上所有的知识材料,此处就不一一列举了,谢谢他们的付出。
写于2017年8月3日 16:36