Kotlin开发Android App和Java的差异10----Kotlin中的泛型(型变 协变 逆变)

1 Java 和 Kotlin 中的泛型

1.1 型变

先看部分代码

Kotlin:

var mutableListOf1 = mutableListOf<Any>()
mutableListOf1.add(1)
mutableListOf1.add("234")

println(mutableListOf1[1])

Java:

List list = new ArrayList();
list.add(1);
list.add("234);

println(list.get(1))   //报错  类抓换异常 CastException

如果熟悉Java的泛型,可以知道,Java在编译是泛型擦除的,所以在没有声明泛型类型时,List就是List<Object>类型,可以往里放任何类型的数据;但是在取出数据的时候,就报错,这就说明,List<String>并不是List<Object>的子类,Java的泛型不是型变的

但是Kotlin就不会存在这个问题,即便是Any类型的集合,在取数据时依然可以取出没有报错,这就是型变

1.2 协变

那Java中的泛型不是型变的,我要怎么才能正确地取出数据呢?一种就是声明确切的泛型,例如List<String>,只能传入String类型,取出的也是String类型;还有一种方式就是通配符

List<? extends UserInfo> list = new ArrayList<Student>();

list集合声明了通配符泛型 ? extends A ,这就是定义了上限的协变,只能从中取出数据,但是不能存数据,取出数据是UserInfo,是安全的;

Kotlin中定义的协变是通过out关键字,out关键字修饰的泛型,只能出现在返回值,不能作为输入值消费,只可取

interface clsA<out T>{

    fun get() : T
}

1.3 逆变

与协变相反的是,在Java中,使用super关键字 ? super A 定义了下限的逆变,此种方式只能存储数据,不能取出数据,因为不知道其中存储的是super的哪个父类,存储安全

与Java对应的,Kotlin中是通过in 关键字修饰协变泛型,通过in修饰的只能在输入值,不能作为返回值,也是存储安全的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Awesome_lay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值