文章目录
1. Kotlin 反射
Kotlin 的反射需要集成 org.jetbrains.kotlin:kotlin-reflect
仓库,版本保持与 kotlin 一致。
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
1.1 Kotlin 反射类图
图片引用《Kotlin 核心编程》
Java 的反射类图
通过 kotlin 和 java 的对比,更容易理解 kotlin 的反射
- Kotlin 的反射类都是基于
KAnnotatedElement
, 而 Java 的反射类都是基于AnnotateElement
; - Kotlin 的 KCallable 和 Java 的 AccessiableObject 都是可用元素;
- Kotlin 的 KProperty 和 Java 的 Field 不太相同。 Kotlin 的 KProperty 通常指相应的 Getter 和 Setter 整体作为一个 KProperty(不存在字段的概念),而 Java 的 Field 通常仅仅指字段本身。
日常使用的 Kotlin 反射
-
创建实例
- ReflectA::class
- KClass.createInstance
- KClass.primaryConstructor 主构造函数
-
获取实例的函数
- 本身及父类的函数 KClass.functions
- 本身声明的函数 KClass.declaredFunctions
- 拓展的函数 KClass.memberExtensionFunctions
-
获取实例的成员变量
- 本身的成员属性 KClass.declaredMemberProperties
- 拓展属性 KClass.memberExtensionProperties
-
获取实例的 companion
KClass.companionObject -
获取注解
KClass.annotations -
获取内部类
KClass.nestedClasses
2.创建实例
无参构造
val clazz = ReflectA::class
val inst2 = clazz.createInstance()
有参构造
val cons1 = clazz.primaryConstructor
val inst1 = cons1?.call(参入参数)
// 或者
val cons2 = clazz.constructors
cons2.get[i].call(参入参数)
说明
- KClass.createInstance 是调用无参数的构造函数
- KClass.primaryConstructor 是主构造函数,如果有参数,可以调用它的 call 方法传入参数
例子
后面的例子都是以 ReflectA
类为例
//定义注解
annotation class Anno
@Deprecated("该类已经不推荐使用")
@Anno
class ReflectA(val name: String) {
companion object{
const val TAG = "ReflectA"
fun show(){
}
}
var age: Int = 0
constructor() : this("ReflectA_")
constructor(name: String, age: Int) : this(name) {
this.age = age
}
fun print(str: String) {
println("ReflectA print str $str")
}
fun sayHi(): String {
println("ReflectA sayHi")
return "sayHi"
}
class InnerClass
}
// 拓展方法
fun ReflectA.exfun() {
println("exfun")
}
// 拓展属性
val ReflectA.foo: Double
get() = 3.14
调用的例子:
println("---------- 创建对象 ---------")
println(" ")
println("createInstance 创建实例")
// createInstance() 方法调用无参数的构造器创建实例
val inst2 = clazz.createInstance()
println(inst2.name)
println(inst2.age)
println(" ")
// primaryConstructor 主构造函数
val cons1 = clazz.primaryConstructor
val inst1 = cons1?.call("hello reflect") // 参入参数
println(inst1)
println("inst1 " + inst1?.name)
println(" ")
println("第一个构造函数")
val cons2 = clazz.<