Kotlin基础 reified关键字

一,背景

常规情况下,使用泛型方法时不能直接访问泛型的具体类型,

举一个例子:定义一个泛型方法,这个方法的功能是打印 value 的值,同时打印value的 class 类型。

kotlin 复制代码
fun <T> getValue(value: T) {
    print("value 的值为 ${value};value 的类型为 ${T::class.java}")
	
}

这时会报错:Cannot use 'T' as reified type parameter. Use a class instead,意思是不能使用 T 作为具体化的类型。

如果我们想在方法内部访问泛型的具体类型怎么办?kotlin 中提供了关键字 reified,使用 reified 修饰泛型后,就允许我们在方法内部使用泛型的具体类型了。(注意reified需要搭配inline使用)

二,reified 的作用:在方法内部访问泛型的具体类型

如果想在方法内部访问泛型的具体类型,使用关键字 reified 修饰泛型,同时方法声明为内联函数,这样就可以在方法内部访问泛型的具体类型了,如下:

kotlin 复制代码
inline fun <reified T> getValue(value: T) {
    print("value 的值为 ${value};value 的类型为 ${T::class.java}")
}

然后调用该方法打印一个具体字符串:

kotlin 复制代码
class Utils {
    fun main() {
        getValue("name")
    }

    inline fun <reified T> getValue(value: T) {
        print("value 的值为 ${value};value 的类型为 ${T::class.java}")
    }
}

打印输出:value 的值为name; value 的类型为String.class。

三,为什么在 reified 修饰的泛型 T 的方法内部可以拿到泛型的具体类型

上面的代码,反编译的代码如下:

ini 复制代码
public final class Utils {
   public final void main() {
      Object value$iv = "name";
      int $i$f$getValue = false;
      String var4 = "value 的值为 " + value$iv + ";value 的类型为 " + String.class;
      System.out.print(var4);
   }

   // $FF: synthetic method
   public final void getValue(Object value) {
      int $i$f$getValue = 0;
      StringBuilder var10000 = (new StringBuilder()).append("value 的值为 ").append(value).append(";value 的类型为 ");
      Intrinsics.reifiedOperationMarker(4, "T");
      String var3 = var10000.append(Object.class).toString();
      System.out.print(var3);
   }
}

main 方法中直接内联了 getValue 方法的内部逻辑,直接将泛型的具体类型 String.class 硬编码到了 main 方法中,即访问到了调用泛型方法时泛型的具体类型。

四,使用场景:

1,封装 startActivity 方法

不使用 reified 时,启动 activity 需要 class 对象,我们必须手动传进来,因为我们无法知道泛型在使用时的具体类型。

kotlin 复制代码
fun <T: Activity> Activity.startActivity(clazz: Class<T>) {
    startActivity(Intent(this, clazz))
}

使用 reified 时,启动 activity 时可以直接拿到泛型方法使用时泛型的具体类型,不需要将 class 手动传进来。

kotlin 复制代码
inline fun <reified T : Activity> Activity.startActivity() {
    startActivity(Intent(this, T::class.java))
}
相关推荐
2501_9159214319 分钟前
iOS 是开源的吗?苹果系统的封闭与开放边界全解析(含开发与开心上架(Appuploader)实战)
android·ios·小程序·uni-app·开源·iphone·webview
allk551 小时前
OkHttp源码解析(一)
android·okhttp
allk551 小时前
OkHttp源码解析(二)
android·okhttp
2501_915909064 小时前
原生 iOS 开发全流程实战,Swift 技术栈、工程结构、自动化上传与上架发布指南
android·ios·小程序·uni-app·自动化·iphone·swift
2501_915909064 小时前
苹果软件混淆与 iOS 代码加固趋势,IPA 加密、应用防反编译与无源码保护的工程化演进
android·ios·小程序·https·uni-app·iphone·webview
2501_916007474 小时前
苹果软件混淆与 iOS 应用加固实录,从被逆向到 IPA 文件防反编译与无源码混淆解决方案
android·ios·小程序·https·uni-app·iphone·webview
介一安全4 小时前
【Frida Android】基础篇6:Java层Hook基础——创建类实例、方法重载、搜索运行时实例
android·java·网络安全·逆向·安全性测试·frida
沐怡旸8 小时前
【底层机制】【Android】深入理解UI体系与绘制机制
android·面试
啊森要自信8 小时前
【GUI自动化测试】YAML 配置文件应用:从语法解析到 Python 读写
android·python·缓存·pytest·pip·dash
下位子9 小时前
『AI 编程』用 Codex 开发识字小帮手应用
android·openai·ai编程