kotlin从小白到大神Day06 2020.7.19

本文详细介绍了Kotlin中的反射机制,包括如何使用KClass创建对象,利用反射调用方法和属性,以及反射顶层方法等内容。通过实例展示了反射在程序运行过程中的动态调用能力。

这个反射还要再学一遍

内容

1.反射的基本使用
2.使用KClass创建对象
3.利用反射调用方法
4.利用反射调用属性
5.反射顶层方法

一.反射的基本使用

Java中的字节码文件是 .class
kotlin中的字节码文件时 .KClass

import kotlin.reflect.full.*

//反射
//在程序运行过程中动态地调用类的属性和方法
fun main() {
    //如何获取字节码文件类型
    //1.只知道这个类型
    val clz = Person::class

    //2.已经有对象了
    val xw = Person()
    val clz2 = xw.javaClass.kotlin

    //可以通过class对象获取类的详细信息
    println(clz.simpleName)//类名
    println(clz.qualifiedName)//全类名  有详细包路径,如 fanshe.Person
    //println(clz.supertypes) kotlin中所有类继承 Any

    //获取类的属性
    clz.memberProperties.forEach { println(it) }//获取自己和父类的所有属性
    clz.declaredMemberProperties.forEach { println(it) }//获取自己的属性

    clz.primaryConstructor.also { println(it) }//获取主构造函数
    clz.constructors.also { println(it) }//获取所有的构造函数
    
    clz.memberFunctions.forEach { println(it) }//获取自己和父类的所有方法(有Any里面的)
    clz.declaredMemberFunctions.forEach { println(it) }//获取自己声明的方法(没有Any里面的)
    clz.functions.forEach { println(it) }//自己和父类的所有的,和memberFunctions基本差不多
}
open class Father
class Person:Father(){
    var name: String = "小王"
    var age = 19
}

二.使用KClass创建对象

import kotlin.reflect.KClass
import kotlin.reflect.full.*


fun main() {
    //获取类的对象 KClass
    //将Any类型转化为Person类型
    //即Person.KClass -> Any -> Person
    val xw = createObj(Person::class) as Person

    println(xw.name)
}

//创建对象
fun createObj(clz: KClass<out Any>): Any{
    //1.使用默认  无参  的构造函数创建
    //return clz.createInstance()//即使用它的时候必须提供一个无参的构造函数

    //2.使用有参数的构造函数创建
    val priConstr = clz.primaryConstructor
    return priConstr!!.call("老王")
}

open class Father
class Person(var name: String = "小王"):Father(){
    var age = 19

    constructor():this("小王"){

    }
}

三.利用反射调用方法

import kotlin.reflect.KClass
import kotlin.reflect.full.*


fun main() {
    invokeFun(Person::class,"show")//my name is 小王 des:老王
}

//调用函数
fun invokeFun(clz: KClass<out Any>,funName: String){
    //一般地,我们调用函数时,都是这样: Person().show("ssss"),即先创建对象,然后通过对象调用函数

    //首先,获取默认的主构造函数
    val priCons = clz.primaryConstructor
    //创建对象
    val obj = priCons?.call("小王")

    //然后,查找你要调用的这个函数是否存在
    for(func in clz.functions){
        if(func.name == funName){
            //当调用类里面的方法时,必须将对象传递过去
            //默认第一个参数就是函数的对象
            //获取参数的个数
            func.parameters.forEach{
                //print("第${it.index},个参数")
                //print("参数类型为: ${it.type}")
            }
            func.call(obj,"老王")
            break
        }
    }
}

open class Father
class Person(var name: String = "小王"):Father(){
    var age = 19

    constructor():this("小王"){

    }

    fun show(des: String){
        println("my name is $name des:$des")
    }
}

四.利用反射调用属性

import kotlin.reflect.KClass
import kotlin.reflect.KMutableProperty1
import kotlin.reflect.full.*


fun main() {

    invokeProperty(Person::class,"age")
}

//访问属性
fun invokeProperty(clz:KClass<out Any>,propName: String){
    //平时访问属性就是 Person().name这种

    //首先,创建对象
    val primary = clz.primaryConstructor
    val obj = primary?.call("Android")

    //然后,查找age属性
    clz.memberProperties.find { it.name == propName }.also {
        //调用对象的get方法
        val value = it?.call(obj)
        //println("获取属性${propName}的值: $value")//获取属性age的值: 19

        //调用对象的set方法
        //将KProperty类型转化为KMutableProperty类型
        //如果属性的修饰符为private,则需要设置isAccessible为true
        if(it != null) {
            val mpro = it as KMutableProperty1<Any, Any>

            mpro.set(obj!!, 18)

            val result = it.call(obj)
            println(result)//输出了 18
        }
    }
}
open class Father
class Person(var name: String = "小王"):Father(){
    var age = 19

    constructor():this("小王"){

    }

    fun show(des: String){
        println("my name is $name des:$des")
    }
}

五.反射顶层方法

import kotlin.reflect.KClass
import kotlin.reflect.KMutableProperty1
import kotlin.reflect.full.*

fun test(){
    println("测试")
}
fun main() {
    val func = ::test
    func.call()//输出 测试

}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值