本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《 阿里云开发者社区用户服务协议 》和 《 阿里云开发者社区知识产权保护指引 》。如果您发现本社区中有涉嫌抄袭的内容,填写 侵权投诉表单 进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

0x7、Kotlin中的型变


和Java泛型一样,Kotlin中的泛型也是「 不变的 」,没有「 通配符类型 」,但有两个其他的东西:「 声明处型变 」(declaration-site variance)  与 「 类型投影 」(type projections)


① 声明处型变


其实就是用「 out 」和「 in 」关键字来替换


  • out 协变 ,等同于Java中的<? extends>, 能读不能写 ,代码示例如下:


image


  • in 逆变 ,等同于Java中的<? super>, 能写不能读 ,代码示例如下:


image


② 类型投影


其实就是对应Java中的*通配符:


  • Java中<?>等同于<* extends Object>


  • Kotlin中 <*> 等同于 out Any


0x7、Kotlin获取泛型类型


在Kotlin中可以通过下述四种方法获取泛型的类型(前两种Java也适用):


① 匿名内部类


原理: 匿名内部类的声明在编译时进行,实例化在运行时进行 代码示例如下


image


② 反射


获取运行时泛型参数类型 ,子类可获得父类泛型的具体类型。 代码示例如下


image


③ 实例化类型参数代替类引用


定义一个扩展函数用于启动Activity,代码示例如下:


fun <T: Activity> FragmentActivity.startActivity(context: Context, clazz: Class<T>) {
    startActivity(Intent(context, clazz))
// 调用
startActivity(context, MainActivity::class.java)


④ 内联函数


Kotlin中使用「 inline 」关键字定义一个内联函数,配合「 reified 」具体化(类型不擦除),得到使用泛型类型的Class。修改后的代码示例如下:


inline fun <reified T : Activity> Activity.startActivity(context: Context) {
    startActivity(Intent(context, T::class.java))
// 调用
startActivity<MainActivity>(context)


参考文献:




什么?泛型本身也可以是nullable?上来就抛这么个问题实在是不够友好~ 首先回顾,什么是泛型?[Oracle Java Tutorials](https://docs.oracle.com/javase/tutorial/extra/generics/index.html) > Introduced in J2SE 5.0, this long-awaited enhancemen
manerfan