欢迎光临散文网 会员登陆 & 注册

DEVLOG 9.25 Kotlin泛型

2021-09-24 20:32 作者:房顶上的铝皮水塔  | 我要投稿

Java中的泛型

Java中的泛型是不形变的,List<String> 并不是List<Object>的子类型。这样做的一个好处是避免因为类型产生的异常(数组是形变的):

PECS: producer extends, consumer super

? extends E 表示此方法接受E和E的子类型。可以读(producer)不可以写。因为已知是E的子类型,可以使用E承接(上转型)

? super E 表示此方法接受E和E的父类型,可以写不可以读 ???


Kotlin中的泛型

1. 泛型介绍

可以通过where指定类型参数T的范围

2. 类型擦除

谈到Java的类型擦除要说明两个重点:

  • Java的List是不变的,数组是协变的。

  • Java的数组在运行时可以获取自身的类型,但是List不行:

Kotlin中的泛型机制和Java中的相同。Java和Kotlin中的泛型在编译之前会检查类型是否存在问题,但是在编译之后通过强制类型转换等方式保证泛型特性。

如何在运行时获取类型信息?

这种方式不能支持带有类型参数的类获取class对象。

使用匿名内部类,匿名内部类在初始化阶段你就会绑定父类或者父接口的相应信息:

使用Kotlin的特性打破类型不变!

在Java中下面的代码是行不通的:

在Kotlin中以下的代码是可以运行的:

这里需要说明一点,在Kotlin中的List和Java中的List定义不同:

比Java中多了out,(但是ArrayList是相同的)。也就是说Kotlin中的ArrayList<String>(List<String>)是List<Any>的子类型。

支持协变的List和它要付出的代价

如果支持协变的话会使得List存在安全问题。因为List<String>是List<Any>的子类型,然后往里面存储内容的时候可以放任何Any的子类。所以在Kotlin中,List并不能存储内容:

也就是说支持协变的List不能将类型参数作为方法参数

支持逆变的Comparator

Comparator需要支持逆变。

但是支持逆变的泛型类型参数不能作为方法的类型参数。考虑上面的情况,List<in T>可能会存入一个T的父类,向下转型是不安全的。但是逆变不影响泛型参数作为方法的返回值


所以总的来说和Java中类似,out支持协变,可以当做producer;in支持逆变,可以当做consumer。


可以这样记:in->输入-> 方法参数 out->输出->返回值


DEVLOG 9.25 Kotlin泛型的评论 (共 条)

分享到微博请遵守国家法律