Kotlin反射
正如在前面不少代码中所见到的, Kotlin也提供了反射 API,这些反射 API可以方便程序在运行时自省程序的结构 。 Kotlin把函数和属性当成“ 一等公民”, 并可通过反射直接获取函数、属性的引用。
使用 Kotlin的反射API需要添加单独的JAR文件(kotlin-reflect.jar),这样可以方使程序在不使用反射时减小运行库的大小。
类引用
Kotlin的类引用使用 KClass代表,如果要获取己知的 Kotlin类的 KClass对象,则可通过如下语法 :
val c = MyClass : :class
上面这种语法在前面程序中已经多次见到。需要说明的是,Kotlin的类引用是 KClass 对象, Java 的类引用是 java.lang.Class 对象,它们二者是不同的,如果需要通过KClass 获取对应的 java.lang.Class 对象,则可调用 KClass 对象的 java 属性 。
如果己有一个Kotlin对象, 则同样可通过::class语法来获取该对象的类引用。例如如下语法:
val c = myObj : :class
从KClass获取类信息
获取 KClass对象之后,即可通过KClass提供的大量方法或属性来获取该 KClass对象所对应类的详细信息。
下面程序示范了通过 KClass 来获取类的详细信息。该程序示范了 KClass 所包含的部分属性和方法
import kotlin.reflect.full.*
//定义注解
annotation class Anno
//使用 3 个注解修饰该类
@Deprecated("该类已经不推荐使用 ")
@Anno
@Suppress(" UNCHECKED CAST")
class ClassTest(age: Int) {
var name: String = "Kotlin"
//为该类定义一个私有的构造器
private constructor() : this(20) {
}
//定义一个有参数的构造器
constructor(name: String) : this(15) {
println("执行有参数的构造器:${name}")
}
//定义一个无参数的 info 方法
fun info() {
println("执行无参数的 info 方法 ")
}
//定义一个有参数的 info 方法
fun info(str: String) {
println("执行有参数的info方法,其str参数值:$str")
}
//定义一个测试用的嵌套类
class Inner
}
//为 ClassTest 定义扩展方法
fun ClassTest.bar() {
println("扩展的 bar 方法")
}
//为 ClassTest 定义扩展属性
val ClassTest.foo: Double
get() = 2.4
fun main(args: Array) {
//下面代码可以获取 ClassTest 对应的 KClass
val clazz = ClassTest::class
//通过 constructors 属性获取 KClass 对象所对应类的全部构造器
val ctors = clazz.constructors
println("ClassTest 的全部构造器如下: ")
ctors.forEach {
println(it)
}
println("ClassTest 的主构造器如下: ")
println(clazz.primaryConstructor)
//通过 functions 属性获取该 KClass 对象所对应类的全部方法
var funs = clazz.functions
println("ClassTest 的全部方法如下: ")
funs.forEach {
println(it)
}
//通过 declaredFunctions 属性获取该 KClass 对象 本身所声明的全部方法(不包括继承的方法)
val funs2 = clazz.declaredFunctions
println("ClassTest 本身声明的全部方法如下: ")
funs2.forEach {
println(it)
}
//通过 declaredMemberFunctions 属性获取该 KClass 对象 本身所声明的全部成员方法(不包括继承的方法〉
val memberFunctions = clazz.declaredMemberFunctions
println("ClassTest 本身声明的成员方法如下: ")
memberFunctions.forEach {
println(it)
}
//通过 memberExtensionFunctions 属性获取该 KClass 对象 所代表类的全部扩展方法(不包括继承的方法)
val extensionFunctions = clazz.memberExtensionFunctions
println("ClassTest 本身声明的扩展方法如下: ")
extensionFunctions.forEach {
println(it)
}
//通过 declaredMemberProperties 属性获取该 KClass 对象 本身所声明的全部成员属性(不包括继承的属性〉
val memberProperties = clazz.declaredMemberProperties
println("ClassTest 本身声明的成员属性如下: ")
memberProperties.forEach {
println(it)
}
//通过 memberExtensionProperties 属性获取该 KClass 对象 所代表类的全部扩展属性(不包括继承的属性〉
val extension