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))
}
相关推荐
程序员卷卷狗7 小时前
MySQL 慢查询优化:从定位、分析到索引调优的完整流程
android·mysql·adb
写点啥呢8 小时前
Android Studio 多语言助手插件:让多语言管理变得简单高效
android·ai·ai编程·多语言
泥嚎泥嚎10 小时前
【Android】给App添加启动画面——SplashScreen
android·java
全栈派森10 小时前
初见 Dart:这门新语言如何让你的 App「动」起来?
android·flutter·ios
q***985210 小时前
图文详述:MySQL的下载、安装、配置、使用
android·mysql·adb
恋猫de小郭10 小时前
Dart 3.10 发布,快来看有什么更新吧
android·前端·flutter
恋猫de小郭12 小时前
Flutter 3.38 发布,快来看看有什么更新吧
android·前端·flutter
百锦再17 小时前
第11章 泛型、trait与生命周期
android·网络·人工智能·python·golang·rust·go
会跑的兔子18 小时前
Android 16 Kotlin协程 第二部分
android·windows·kotlin
键来大师18 小时前
Android15 RK3588 修改默认不锁屏不休眠
android·java·framework·rk3588