0x7、Kotlin中的型变
和Java泛型一样,Kotlin中的泛型也是「不变的」,没有「通配符类型」,但有两个其他的东西:「声明处型变」(declaration-site variance) 与 「类型投影」(type projections)
① 声明处型变
其实就是用「out」和「in」关键字来替换
- 「out」协变,等同于Java中的<? extends>,能读不能写,代码示例如下:
- 「in」逆变,等同于Java中的<? super>,能写不能读,代码示例如下:
② 类型投影
其实就是对应Java中的*通配符:
- Java中<?>等同于<* extends Object>
- Kotlin中<*>等同于out Any
0x7、Kotlin获取泛型类型
在Kotlin中可以通过下述四种方法获取泛型的类型(前两种Java也适用):
① 匿名内部类
原理:匿名内部类的声明在编译时进行,实例化在运行时进行。代码示例如下:
② 反射
获取运行时泛型参数类型,子类可获得父类泛型的具体类型。代码示例如下:
③ 实例化类型参数代替类引用
定义一个扩展函数用于启动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)