最近看了一下讲解反射知识的文章,但是感觉非常的晦涩难懂,就研究了一段时间,以下纯个人见解
从“元”这个概念来引入反射这个话题,
Meta(元):在计算机领域通常指“关于自身”或“更高一层的抽象”
比如对于“数据”,元数据就是描述数据的数据,是他更高一层的东西
而kotlin就依赖于这个“元数据”,分别有类的元数据,函数的元数据,属性的元数据–>反射就是来获取这些更高一层的“元”信息的
在这里用KClass来表示类的元信息,KFunction来表示函数的元信息,KProperty来表示属性的元信息—–>都是使用“::”来获取的
这里通过类名反射来获取一个String类的元信息KClass

这里说明一下类型,
通过类名::class 返回 类型为KClass<T>,是编译期就确定的类元信息,
通过实例::class 返回 类型为KClass<out T>,运行时取实例的实际类型
上面是通过类名反射的,也可以通过实例来反射获取类的元信息

第一个打印String 第二个打印Kotlin String
通过获取类的元信息,也就可以获取他的构造函数了(并创建对象)
这边先写一个实例类

然后反射后通过.constructors.first() 来获取他的构造函数 .call来调用,(call里传形参)
注意调用构造函数之后是创建了一个类实例

这个.call()很重要,顺着这个支线,来讲第二个KFunction
kotlin可以通过反射函数来调用函数
比如先写一个带有成员函数的类,并且获取这个函数的元信息

注意这个成员函数没有形参
然后就可以用.call()来调用这个函数
思考一下这里该怎么调用,是不是KFunction.call( )就可以了?可以试一下

运行一下试试

Callable expects 1 arguments, but 0 were provided.提示这个.call()需要一个参数但是我没传
这下来思考一下,需要一个什么参数,为什么需要参数
分析一下,这里是要调用类的成员函数,但是类能直接调用成员函数吗?肯定不行的,必须是类的对象(也就是实例化类)才可以调用。
那这里也是同理,我反射获取函数的元信息,但是我要调用它缺一个实例化的类,
对的 需要一个实例化类参数,因为需要调用类的成员函数
.call()的第一个参数是来表示receiver接收者,
所以需要改为:

play()是实例化的对象了,调用的成员也没有形参,这样就可以了 是对的
那再稍微复杂一点,瞎吊弄一个

这该怎么调用呢,分析一下,call第一个参数要实例化play1函数,要写入sex参数,后面的参数来填入构造函数的形参

最后一个就是通过反射来获取属性的元信息了—->也就是可以获取属性的值或者设置属性
创建一个实例类

上面是通过类:: 函数来反射的,这里就是类::属性来反射

拿到了属性的元信息,怎么通过这个元信息来读他的值呢?—>用.get()
但前提他得有值吧,所以还是要实例化一下类拿到对象

然后.get()里面传入这个实例化对象test就可以读了

也可以对属性进行一些设置,但得先判断一下属性是可变的(var)

调用setter函数来对属性设置新值(在之前的文章讲过)。
就扯到这 溜了




