Kotlin Inline Function 2
Kotlin - Inline Functions 2
Reified Type
runtime-available语义
定义部分内容翻译自官方文档:Semantics, Checks and Restrictions
什么是 runtime-available 类型?
- Kotlin的object、class、trait(已被废弃) 也被称为 classifier
- 类型参数为空或者全部类型参数都被reified关键词修饰的classfier。Nothing 是一种例外情况。
- 一个classifier有多个类型参数,但是每一个类型参数都是被reified修饰的runtime-available类型或者star-project(*)
- (没有指classifier,也就可以是函数)拥有一个类型参数T,T被reified关键词修饰。
runtime-available的限制性
- 不是runtime-available的不允许放在is, !is, as, as?等右边操作符的右边。
- 只有单类型参数的inline function的类型参数能够用reified标记。
- Kotlin原生的Array类型是唯一一个类型参数能够使用reified来标记的。
- 只有 runtime-available 的类型能够被当作一个参数传给 reified类型参数。
Note: 坦白地说官方这部分文档所表达出来的意思跟实际情况(Kotlin - 1.2.20)是有些出入的,也不知道是文档没有及时更新,还是Kotlin这部分特性后面还需要继续迭代更新。但不影响我们学习 inline function reified。
reified作用
inline function reified 的典型使用场景是像反射这样,需要在运行时动态获取类型信息的情况。官方网站给了以下一个例子:
1 | //声明 |
1 | //使用 |
上面这使用例子并没有展示reified的真正作用,仅仅是展示了如何声明reified和调用被reified声明的inline functions。各位看官可以试试将reified拿掉,例子照样能正常工作。
真正体现reified作用的使用例子是下面这个:
1 | inline fun <reified T> membersOf() = T::class.members |
如果不加reified修饰,编译器是会报错的。因为被reified修饰的类型参数在编译期进行内联的时候就会被转为对应class的符号引用。下面这个例子清楚地展示了这个转换:
1 | //Source code C.Kt |
compiled之后:
1 | public final class com.maxtropy.viewtest.CKt { |
第9行字节码指令指示从常量池中加载String类型信息的常量,也就是String的符号引用。这个时候String类型常量处于操作栈栈顶,因此第11行字节码操作指令都是作用在他上面,创建了一个包含String类型信息的KClass类型实例;并在第12行,
通过getMembers方法获取其中的信息。