[Kotlin] 泛型实例化

在 Kotlin 中,由于泛型的强化,以及阻止擦除等特性的存在,使得泛型实例化成为了可能,因此我们可以写出类似于以下的函数:

fun <T: Any> new(): T

在 Java 中要实现这类函数无疑是困难的。那么下面来看一下 Kotlin 具体要怎么做吧,首先我们必须阻止泛型擦除:

inline fun <reified T: Any> new(): T

通过 inlinereifiied 可以保证泛型类型被实化,这是实例化的基础,接着就可以写以下代码:

inline fun <reified T: Any> new(): T {
    val clz = T::class.java
    val mCreate = clz.getDeclaredConstructor()
    mCreate. isAccessible = true
    return mCreate. newInstance()
}

这就是最基础的泛型实例化了,然鹅我们经常会遇到需要带参构造的情况,没有参数的构造只能满足一小部分情况,所以加个参数吧:

inline fun <reified T: Any> new(vararg params: Any): T {
    val clz = T::class.java
    val paramTypes = params.map { it::class.java }.toTypedArray()
    val mCreate = clz.getDeclaredConstructor(*paramTypes)
    mCreate. isAccessible = true
    return mCreate. newInstance(* params)
}

那么有了这个函数之后,可以做些什么呢?比如说在 swing 下进行 UI 组件的实例化(其实就是想把代码写成 SwiftUI 2333):

fun button(text: String, block: JButton.() -> Unit) = new<JButton>(text).also(block)

fun main(args: Array<String>) {
    button("Click") {
        addActionListener { ... }
    }
}

好了,下面开始炫技:

inline fun <reified T: Any> new(vararg params: Any) =
    T::class.java.getDeclaredConstructor(*params.map { it::class.java }.toTypedArray()).apply { isAccessible = true }.newInstance(*params)

以上代码作用于 JVM 端,包括 Android 都可以使用,如果是 Kotlin/Native 下使用,可以这么来:

inline fun<reified T: CVariable> new(block: T.() -> Unit): T = memScoped { alloc<T>().also(block) }

于是我们可以在 macostarget 下,写这样的代码:

val sz = new<CGSize> {
    width = 0.0
    height = 0.0
}

这样就初始化了一个 CGSize 对象。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Kotlin 知识梳理系列文章 Kotlin 知识梳理(1) - Kotlin 基础Kotlin 知识梳理(2) ...
    泽毛阅读 7,347评论 0 4
  • 泛型 泛型(Generic Type)简介 通常情况的类和函数,我们只需要使用具体的类型即可:要么是基本类型,要么...
    Tenderness4阅读 5,259评论 4 2
  • Kotlin 调用 Java 由于 Kotlin本身并没有提供强大的类库支持,Kotlin只是一种语言,因此 Ko...
    凌寒天下独自舞阅读 14,772评论 0 10
  • 很多家长貌似民主,经常以"协商"的方式和孩子对话,但是协商背后,依然是自己早已确定的目标,所以所谓协商,只是为了引...
    车荣杰爸爸阅读 1,670评论 1 3
  • “石严,我以前一直以为你是聪明人,今天看来不过如此。”武松鄙视的望着他。武松一眼就看出这些来的是什么人:只有方涛和...
    超夫阅读 5,392评论 11 28