KClass
kt 中 Classs 类。其对应的是
java.lang.Class
。
下面所使用的 Test 类定义如下:
class Test {
var name: String = ""
fun test(sex: String, age: Int) = "$sex+$age"
}
-
通过
MyClass::class
获取指定类对应的 KClass 对象。就像在 java 中通过MyClass.class
获取指定类的 Class 对象一样。fun main(args: Array<String>) { val t = Test() val clazz:KClass<Test> = Test::class // 返回一个 KClass 对象 }
-
通过
对象.javaClass.kotlin
获取指定实例对应的 KClass 实例。其中对象.javaClass
可以获取指定类的 java Class 实例。fun main(args: Array<String>) { val t = Test() println(t.javaClass is Class) // true }
-
KClass 与 Class 转换:
对象.javaClass
得到 Class 对象,再.kotlin
得到 KClass 对象类名::class
得到 KClass 对象,再.java
得到 Class 对象。对象::class
得到 KClass 对象,再.java
得到 Class 对象。
属性
KClass 属性如下:
属性 | 含义 |
---|---|
memberProperties | 所有属性,含从父类中继承的 |
annotations | 获取元素上的所有注解。定义于 KAnnotatedElement 中 |
createInstance() | 方法。通过 KClass 创建一个实例 |
objectInstance | 如果类是单例的,则存储其唯一实例。否则为空 |
object Test {
val name = "naan"
fun test() = println("tesss")
}
则 Test::class.objectInstance
其不为空,如果将 object 换成 class ,则值为空
KCallback 与 KFunction,KProperty
KCallback 是函数和属性的超接口。其内部定义有 call 方法,调用该方法就相当于调用函数或者属性的 getter ;KFunction 是 KCallback 的子类,它是函数的接口;KProperty 是 KCallback 的子类,它是属性的接口。
属性 | 含义 |
---|---|
name | 获取方法或属性名 |
parameters | 参数列表 |
三者接收的第一个参数均为执行该方法所需要的对象。就像 java 中执行某个反射方法时,需要为该方法指定一个执行对象。
KFunction 的泛型说明:除最后一个泛型外,其余的均为调用其 invoke 方法时需要传递参数类型,最后一个泛型为 invoke 方法返回值类型。也即对应方法的参数类型列表和返回值类型。
使用 成员引用函数时,返回的是一个 KFunction 实例。调用其 invoke 就相当于执行该方法:
-
使用 成员引用属性时,返回的是一个 KProperty 实例。调用其
get
相当于调用该实例的 getter 方法:KProperty KProperty 泛型说明:第一个参数表示接收者类型,第二个参数表示属性类型。
对于 var 修饰的变量,通过 KProperty 定义 set 方法修改其值。但对不可变变量,没有 set 方法。
parameters 返回的参数列表中,第一个参数为 receiver,表示执行当前方法的实例。
继承关系
因为所有的声明都可以被注解(KAnnotatedElement 类的作用),所以 KClasss,KCallback,KParameter 都继承于 KAnnotatedElement。
KProperty 只有 get 方法,用于 val 声明的变量
KMutableProperty 有 set 方法,用于 var 声明的变更。
两者内部有 getter/setter 接口,用于获取相应属性的 getter/setter 方法。getter/setter 接口都继承于 KFunction,因此可以把他们当作函数调用。
fun main(args: Array<String>) {
val test = Test::name
val t = Test()
println(test.getter.invoke(t))
test.setter.invoke(t,"yyy")
println(test.getter.invoke(t))
}
构造函数
通过
KClass#constructors
可以获取所有的构造函数。
构造函数也是函数,因此每一个构造函数都是 KFunction 的子类。故而可以调用 call 方法创建实例
fun main(args: Array<String>) {
val kclzzz = Test::class
val t = kclzzz.constructors
t.forEach {
val i = it.call("name", 20)
println(i)
}
}
data class Test(val name: String, var age: Int = 10)
但 call 方法不支持默认参数,即上面创建实例时,即使 Test 类中 age 已经指定了默认值 10 ,调用 call() 时也必须传入一个对应的实参。
callBy
callBy 定义在 KCallback 类中。
与 call() 方法相比,它接收一个 map —— map 存储了方法形参与其实参之间的对应关系。
- 如果 map 缺少形参,则该形参会使用默认值,如果有默认值的话
2.形参的顺序不必和方法中一样
- map 中值的类型需要跟构造方法中参数类型一致。
KParameter
方法参数
name 表示参数名
type 表示参数类型
isOptional 表示该参数是否有默认值。true 表示有默认值,false 没有。