为了活动小家电-注解Annotation(三)

68 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的25天,点击查看活动详情

为了活动小家电,接着上篇搞!

自定义注释(使用反射)

现在我们要创建一个自定义注释。

创建Custom Annotation时,有一种使用Reflection的方法,也有一种使用Code Generation的方法。

反射是一个强大的功能,它会在运行时改变代码结构,但应该谨慎使用,因为它很危险。

反射不是我个人的偏好,因为它会导致应用程序性能不佳。
比如Reflection中,每次调用函数时,都会检查参数个数是否正确,参数类型是否正确等。这会造成性能损失,因为 JIT 编译器每次都会执行它在运行时只会执行一次的操作。当然,现在它快了一点,但我还是不建议过度使用它。

在 Kotlin 中使用反射最基本的方法是使用 KClass。

如果只使用KClass,运行时会崩溃,所以需要先添加kotlin-reflection库。

implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"

下面是您可以使用 KClass 做什么的示例。

    @Deprecated("已遗弃")
    class Dididi {
        var field1 = ""
        var field2 = 0
        fun function1() {}
        fun function2() {}
    }

    // 测试方法
    fun kClassTest() {
        val receiverA = Dididi()
        val kClass = Dididi::class

        // Class 元数据
        LogUtils.v(TAG, kClass.simpleName!!)
        LogUtils.v(TAG, kClass.isData)
        LogUtils.v(TAG, kClass.isAbstract)
        LogUtils.v(TAG, kClass.isCompanion)
        LogUtils.v(TAG, kClass.isFinal)
        LogUtils.v(TAG, kClass.isInner)
        LogUtils.v(TAG, kClass.isOpen)
        LogUtils.v(TAG, kClass.isSealed)

        // 创建实例
        LogUtils.v(TAG, kClass.createInstance())

        // 构造函数
        LogUtils.v(TAG, kClass.constructors.map { it.name })
        LogUtils.v(TAG, kClass.constructors.map { it.parameters })
        LogUtils.v(TAG, kClass.constructors.map { it.call() })

        // 注解
        LogUtils.v(TAG, kClass.annotations.map { it.annotationClass.simpleName })

        // 字段
        val kProperty = kClass.memberProperties.find { it.name == "field1" }
        (kProperty as KMutableProperty<String>).setter.call(receiverA, "Changed Field1 Value")
        LogUtils.v(TAG, receiverA.field1)

        // 方法
        LogUtils.v(TAG, kClass.memberFunctions.map { it.name })
        LogUtils.v(TAG, kClass.memberFunctions.find { it.name == "function1" }?.call(receiverA) ?: "")
    }

结果如下。

A
false
false
false
true
false
false
false

com.example.Test$A@dbc59aa

[<init>]
[[]]
[com.example.Test$A@299b]

[Deprecated]

Changed Field1 Value

[function1, function2, equals, hashCode, toString]
kotlin.Unit

为了活动小家电,下篇继续搞!