Kotlin-reified:泛型实化——泛型高级功能1(第一行代码Kotlin学习笔记11)

目录

  • 1. 泛型实化的原理
  • 2. 泛型实化的应用

如果我们之前是Java程序员,那么我们对泛型就绝对不回陌生了,但是说到泛型的实化,一定就是陌生的了,它可以给我们带来一些新奇而又让你感到高级的功能。

1. 泛型实化的原理

在Java中,泛型是只存在于编译阶段的,这就要我们了解Java中泛型的擦除机制,就是说虽然我们在写代码的时候写了泛型,但是程序真正运行的时候,并不知道我们的具体类型是什么,泛型的约束只在编译时期存在。比如我们写了List< String>集合,在编译时期,我们是无法向该list中添加非String的元素的,但是在运行时期,我们并不能知道该list里放的是哪种元素。也就是说我们写了Lsit< T>,我们并不能在运行的时候遍历该list,然后打印出T.class。因为T的实际类型在运行是已经被擦除了,但是在Kotlin中,我们就有办法实现T::Class.java的相关功能,该原理就叫做泛型的实话。

我们还要知道的是:所有的基于jvm的语言,它们的泛型都是通过类型擦除机制来实现的,但是我们的Kotlin为什么能实现不一样的东西呢,还记得我们在之前学过Kotlin中的高阶函数的内联功能吗?Kotlin-高阶函数详解,inline, noinline, crossinline关键字解析(第一行代码Kotlin学习笔记7),内联函数中的代码会在编译的时候被替换到调用它的地方,这样的话,如果我们在内联函数中使用了泛型,那么编译过后,使用的其实就是该泛型对应的真实类型了。具体使用也很简单,我们只需要在泛型前用reified关键字修饰就可以了:

inline fun <reified T> getType() {}

然后我们就可以实现这样的功能:

inline fun <reified T> getType() = T::class.java
fun main() {
    var type = getType<String>()
    println("tyep is : $type")
}
//tyep is : class java.lang.String

由此可见,我们可以使用泛型,获取到它所对应的真实类型,这样的功能在Java中我们是做不到的,但是,这个功能有什么卵用呢?

2. 泛型实化的应用

如果我们要跳转到某个activity,如OpentActivity,我们会这么写:

val intent = Intent(this,OpentActivity::class.java)
startActivity(intent)

其实以前我们使用Java编程的时候,也是同样的思路,但是,有了泛型的实化,我们就有了更加优雅的处理方式:

inline fun <reified T>startActivity(context : Context){
    val intent = Intent(context,T::class.java)
    context.startActivity(intent)
}

我们首先定义了自己的startActivity()方法,然后,当我们需要启动某个activity时,比如我们依然在某个activity中启动OpentActivity,这样写就可以了

 startActivity<OpentActivity>(this)

如果我们想要在intent中添加我们想要携带的参数怎么办呢?这里就可以使用我们之前学到的高阶函数了,我们可以写一个重载函数:

inline fun <reified T>startActivity(context : Context,block: (Intent.() -> Unit)){
    val intent = Intent(context,T::class.java)
    intent.block()
    context.startActivity(intent)
}

然后可以这样使用:

startActivity<OpentActivity>(this){
    putExtra("key","value")
}

这样使用是不是就比之前方便多了,如果我们有自己的BaseActivity,我们完全可以将此方法定义在BaseActivity,大概就是这个样子:

open class BaseActivity : AppCompatActivity() {

    inline fun <reified T>startActivity() {
        val intent = Intent(this,T::class.java)
        startActivity(intent)
    }

    inline fun <reified T>startActivity(block:Intent.() -> Unit) {
        val intent = Intent(this,T::class.java)
        intent.block()
        startActivity(intent)
    }
}

然后我们的业务activity继承BaseActivity:

class MainActivity : BaseActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        button.setOnClickListener {
            startActivity<OpentActivity>(){
                putExtra("key","value")
            }
        }
    }
}

你可能感兴趣的:(Kotlin,Android,kotlin)