反射

作者: 一江碎月 | 来源:发表于2018-07-16 17:28 被阅读0次

KClass

kt 中 Classs 类。其对应的是 java.lang.Class

下面所使用的 Test 类定义如下:

class Test {
    var name: String = ""
    fun test(sex: String, age: Int) = "$sex+$age"
}
  1. 通过 MyClass::class 获取指定类对应的 KClass 对象。就像在 java 中通过 MyClass.class 获取指定类的 Class 对象一样。

    fun main(args: Array<String>) {
        val t = Test()
        val clazz:KClass<Test> = Test::class  // 返回一个 KClass 对象
    }
    
  2. 通过 对象.javaClass.kotlin 获取指定实例对应的 KClass 实例。其中 对象.javaClass 可以获取指定类的 java Class 实例。

    fun main(args: Array<String>) {
        val t = Test()
        println(t.javaClass is Class) // true
    }
    
  3. 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 参数列表
  1. 三者接收的第一个参数均为执行该方法所需要的对象。就像 java 中执行某个反射方法时,需要为该方法指定一个执行对象。

  2. KFunction 的泛型说明:除最后一个泛型外,其余的均为调用其 invoke 方法时需要传递参数类型,最后一个泛型为 invoke 方法返回值类型。也即对应方法的参数类型列表和返回值类型。

  3. 使用 成员引用函数时,返回的是一个 KFunction 实例。调用其 invoke 就相当于执行该方法:

KFunction 参数,返回值
  1. 使用 成员引用属性时,返回的是一个 KProperty 实例。调用其 get 相当于调用该实例的 getter 方法:

    KProperty
  2. KProperty 泛型说明:第一个参数表示接收者类型,第二个参数表示属性类型。

  3. 对于 var 修饰的变量,通过 KProperty 定义 set 方法修改其值。但对不可变变量,没有 set 方法。

  4. parameters 返回的参数列表中,第一个参数为 receiver,表示执行当前方法的实例。

继承关系

继承关系
  1. 因为所有的声明都可以被注解(KAnnotatedElement 类的作用),所以 KClasss,KCallback,KParameter 都继承于 KAnnotatedElement。

  2. KProperty 只有 get 方法,用于 val 声明的变量

  3. KMutableProperty 有 set 方法,用于 var 声明的变更。

  4. 两者内部有 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 存储了方法形参与其实参之间的对应关系。

  1. 如果 map 缺少形参,则该形参会使用默认值,如果有默认值的话

2.形参的顺序不必和方法中一样

  1. map 中值的类型需要跟构造方法中参数类型一致

KParameter

方法参数

  1. name 表示参数名

  2. type 表示参数类型

  3. isOptional 表示该参数是否有默认值。true 表示有默认值,false 没有。

相关文章

  • Java基础之反射

    Java基础之反射 反射基本介绍 反射的使用通过反射调用属性和方法通过反射获取配置文件 反射基本介绍 Java反射...

  • 镜面反射矩阵的推导

    镜面反射是以镜面作为反射平面,实物与反射物到反射平面的距离相等,实物与反射物方向相反,所以,反射矩阵由反射平面确定...

  • reflect.go包学习_之二 指针操作提高反射性能 反射应用

    reflect.go包学习_之二 指针操作提高反射性能 反射应用 反射创建实例 反射信息、反射调用方法、反射修改值...

  • Java互联网公司-经典面试题附答案

    基础:Java 反射?反射有什么缺点?你是怎么理解反射的(为什么框架需要反射)?优点:反射具有解耦性,缺点:反射属...

  • Java反射与joor反射库的使用

    java原生反射的使用 反射构造对象 反射方法 反射字段 joor反射库的使用 github:https://gi...

  • Java反射

    什么是反射? 反射的作用? 反射性能优化?

  • 反射三定律

    反射第一定律:反射可以将interface类型变量转换成反射对象 反射第二定律:反射可以将反射对象还原成inter...

  • 反射

    1.反射是什么?反射的定义,概念 2.为什么要学反射? 3.怎么使用反射?反射的使用

  • 一周岁前做好两件事,孩子就不会语言迟缓,保证口齿伶俐

    与语言发展相关的原始反射有四个:张口反射、足跖反射、抓握反射和手拉反射,每个反射的发生、发展和整合都是次第进行的,...

  • 面试官问go反射第一弹

    目录 反射概念 reflect包 反射类型(Type)和种类(Kind) 反射类型(Type)使用 反射类型对象(...

网友评论

      本文标题:反射

      本文链接:https://www.haomeiwen.com/subject/kuwbpftx.html