IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Kotlin学习笔记18 反射Part2 -> 正文阅读

[移动开发]Kotlin学习笔记18 反射Part2

参考链接

示例来自bilibili Kotlin语言深入解析 张龙老师的视频

12 通过KClass获取泛型类型参数

/**
 * 通过KClass获取泛型类型参数
 */

class MyTestClass<K,V> {
    val k:K ? = null
    val v:V ? = null
}

fun main() {
    // 获取KClass对象
    val myTestClassType = MyTestClass::class
    // 获取泛型的类型集合
    println(myTestClassType.typeParameters)
    println(myTestClassType.typeParameters.size)
    println("first property type "+myTestClassType.typeParameters[0])
    println("second property type "+myTestClassType.typeParameters[1])
}

class HelloKotlin12 {
}

13 通过KClass获取一个类的父类信息

/**
 * 通过KClass获取一个类的父类信息
 */

class MySerializable:Serializable,MyInterface
interface MyInterface

fun main() {
    val mySerializable = MySerializable::class
    println(mySerializable.superclasses)
}

class HelloKotlin13 {
}

14 通过KClass获取一个类的属性信息

/**
 * 通过KClass获取一个类的属性信息
 */

class MyTestClass2(var a:String,val flag:Boolean,var age:Int)

fun main() {
    val myTestClass2 = MyTestClass2::class
    println(myTestClass2.memberProperties)
}

class HelloKotlin14 {
}

15 通过KClass获取一个类的普通方法

/**
 * 通过KClass获取一个类的普通方法
 */
class MyTestClass3{
    fun printSth(){
        println("printSth")
    }

    fun getSth():String{
        return "getSth"
    }
}

fun main() {
    val myTestClass3 = MyTestClass3::class
    println(myTestClass3.memberFunctions)
}

class HelloKotlin15 {
}

16 通过KClass获取一个类的构造方法

/**
 * 通过KClass获取一个类的构造方法
 */
class MyTestClass4(value: Int) {
    constructor(value: Int, color: String) : this(value) {
        println("secondary constructor with string")
    }

    constructor(value: Int, full: Boolean) : this(value) {
        println("secondary constructor with boolean")
    }
}

fun main() {
    val myTestClass4 = MyTestClass4::class
    val constructors = myTestClass4.constructors
    println(constructors)
}

class HelloKotlin16 {
}

17 通过KClass获取一个类的普通方法并调用

/**
 * 通过KClass获取一个类的普通方法并调用
 * 通过判断方法名称调用
 */
class MyTestClass5 {
    fun printSomething(name: String) {
        println("printSomething $name")
    }

    fun printNothing() {
        println("printNothing")
    }
}

fun main() {
    // 获取MyTestClass5的KClass
    val myTestClass5 = MyTestClass5::class
    val myTestClass5Instance = MyTestClass5()

    // 通过MyTestClass5的KClass 根据方法名查找方法
    val functionToInvoke1 = myTestClass5.functions.find { it.name == "printSomething" }
    // 调用指定instance的相应方法
    functionToInvoke1?.call(myTestClass5Instance, "AAAA")
    val functionToInvoke2 = myTestClass5.functions.find { it.name == "printNothing" }
    functionToInvoke2?.call(myTestClass5Instance)
}

class HelloKotlin17 {
}

18 通过KClass获取一个类的属性并调用其get方法

/**
 * 通过KClass获取一个类的属性并调用其get方法
 * 通过判断属性名称调用
 */
class MyTestClass6() {
    var name: String = "hello"
}

fun main() {
    // 获取MyTestClass6的KClass
    val myTestClass6Class = MyTestClass6::class
    val myTestClass6Instance = MyTestClass6()

    val propertyToInvoke = myTestClass6Class.memberProperties.find { it.name == "name" }
    println(propertyToInvoke?.call(myTestClass6Instance))// 反射调用属性1
    println(propertyToInvoke?.get(myTestClass6Instance))// 反射调用属性2
    println(propertyToInvoke?.getter?.call(myTestClass6Instance))// 反射调用属性3
}

class HelloKotlin18 {
}

19 通过KClass获取一个类的属性并get set它的值

/**
 * 通过KClass获取一个类的属性并get set它的值
 * 通过判断属性名称调用
 */
class MyTestClass7{
    var name: String = "hello"
    var authorName: String = "Tom"
}

fun main() {
    // 获取MyTestClass6的KClass
    val myTestClass7Class = MyTestClass7::class
    val myTestClass7Instance = MyTestClass7()

    val propertyToInvoke = myTestClass7Class.memberProperties.find { it.name == "name" }
    println(propertyToInvoke?.call(myTestClass7Instance))// 反射调用属性1
    println(propertyToInvoke?.get(myTestClass7Instance))// 反射调用属性2
    println(propertyToInvoke?.getter?.call(myTestClass7Instance))// 反射调用属性3
    println(myTestClass7Instance.name)

    if (propertyToInvoke is KMutableProperty<*>){// 反射获取属性的set方法并调用
        propertyToInvoke.setter.call(myTestClass7Instance,"hi")
    }
    println(propertyToInvoke?.call(myTestClass7Instance))// 反射调用属性1
    println(propertyToInvoke?.get(myTestClass7Instance))// 反射调用属性2
    println(propertyToInvoke?.getter?.call(myTestClass7Instance))// 反射调用属性3
    println(myTestClass7Instance.name)
}

class HelloKotlin19 {
}

20 通过KClass获取一个类的伴生对象 并反射调用伴生的方法

/**
 * 通过KClass获取一个类的伴生对象 并反射调用伴生的方法
 */

class MyTestClass8{
    companion object{
        fun method(){
            println("method")
        }
    }
}

fun main() {
    val myTestClass8Class = MyTestClass8::class
    val companionObj = myTestClass8Class.companionObject
    println(companionObj)
    val methodToInvoke = companionObj?.functions?.find { it.name == "method" }
    methodToInvoke?.call(MyTestClass8)// 反射调用

    MyTestClass8.method()//正常调用
}

class HelloKotlin20 {
}

21 通过KClass反射创建实例

/**
 * 通过KClass反射创建实例
 * 反射调用无参构造方法
 */


class MyTestClass9(val value: Int = 0) {
    fun printSomething(name: String) {
        println("printSomething $name")
    }

    fun printNothing() {
        println("printNothing $value")
    }
}

fun main() {
    val myTestClass9KClass = MyTestClass9::class
    // 反射创建实例 调用的是无参构造方法
    val myTestClass9Instance = myTestClass9KClass.createInstance()

    // 反射查找方法并调用指定对象的该方法
    myTestClass9KClass.functions.find { it.name == "printSomething" }
        ?.call(myTestClass9Instance, "AAA")
    myTestClass9KClass.functions.find { it.name == "printNothing" }?.call(myTestClass9Instance)
}

class HelloKotlin21 {
}

22 通过KClass反射调用有参构造方法

/**
 * 通过KClass反射调用有参构造方法
 */

class MyTestClass10(var name: String) {
    var price = 0.0

    constructor() : this("默认商品") {
        price = 0.0
    }

    constructor(name: String, price: Double) : this(name) {
        this.price = price
    }
}

fun main() {
    val myTestClass10KClass = MyTestClass10::class
    // 反射调用无参构造方法
    val myTestClass10Instance = myTestClass10KClass.createInstance()
    println(myTestClass10Instance.name)
    println(myTestClass10Instance.price)

    // 反射调用属性
    println(myTestClass10KClass.memberProperties.find { it.name == "name" }
        ?.call(myTestClass10Instance))
    println(myTestClass10KClass.memberProperties.find { it.name == "price" }
        ?.call(myTestClass10Instance))

    // 反射调用有参构造方法
    val cons = myTestClass10KClass.constructors
    cons.forEach {
        if (it.parameters.size == 2) {
            val instance2 = it.call("python", 34)
            println(myTestClass10KClass.memberProperties.find { it.name == "name" }
                ?.call(instance2))
            println(myTestClass10KClass.memberProperties.find { it.name == "price" }
                ?.call(instance2))
        }
    }
}

class HelloKotlin22 {
}

23 通过KClass获取一个类的普通方法并调用

/**
 * 通过KClass获取一个类的普通方法并调用
 * 通过判断参数个数调用
 */
class MyTestClass11 {
    fun printSomething(name: String) {
        println("printSomething $name")
    }

    fun printNothing() {
        println("printNothing")
    }
}

fun main() {
    // 获取MyTestClass5的KClass
    val myTestKClass11 = MyTestClass11::class
    val myTestKClass5Instance = myTestKClass11.createInstance()

    // 根据参数个数查找普通方法
    val functions = myTestKClass11.functions
    for (function in functions) {
        // 调用1个参数的普通方法
        // 注意对比构造方法的反射调用 因为普通方法比构造方法来说 多一个参数(实例对象)
        // 因此一般一个参数的普通方法 在反射时有两个参数
        if (function.parameters.size == 2) {
            function.call(myTestKClass5Instance, "xxxx")
        }
        // 调用0个参数的普通方法
        if (function.parameters.size == 1) {
            function.call(myTestKClass5Instance)
        }
    }
}

class HelloKotlin23 {
}

24 通过KClass获取一个类的属性并get set它的值

/**
 * 通过KClass获取一个类的属性并get set它的值
 * 通过判断属性名称 并使用KMutableProperty1或KProperty1 调用
 * 可以对比HelloKotlin19的例子
 */

class MyTestClass12 {
    var name: String = "Flutter"
    val price: Double = 34.5
}

fun main() {
    val myTestClass12KClass = MyTestClass12::class
    val myTestClass12Instance = myTestClass12KClass.createInstance()
    // memberProperties是KProperty1类型 只有get方法
    val properties = myTestClass12KClass.memberProperties

    properties.forEach {
        when (it.name) {
            "name" -> {
                // KMutableProperty1 包含了set和get方法
                // 其中的泛型的第一个参数是接收者类型 也是当前属性所依附的对象类型
                // 其中的泛型的第二个参数是当前属性类型
                val kMutableProperty = it as KMutableProperty1<MyTestClass12, String>
                kMutableProperty.set(myTestClass12Instance, "Kotlin")
                println(it.get(myTestClass12Instance))

            }
            "price" -> {
                println(it.get(myTestClass12Instance))
            }
        }
    }

}

class HelloKotlin24 {
}

25 顶层变量的反射 vs 普通变量的反射调用

/**
 *  顶层变量的反射 vs 普通变量的反射调用
 */
class MyTestClass13 {
    // 普通变量
    var name: String = "Flutter"
}
// 顶层变量
var test = "test"
fun main() {
    // 顶层变量的反射调用
    val topProp = ::test
    topProp.set("changed value")
    println(topProp.get())
    println(test)

    // 普通变量的反射调用
    println("==========通过实例反射调用属性========")
    // 通过实例反射调用属性
    val myTestClass13Instance = MyTestClass13::class.createInstance()
    val name = myTestClass13Instance::name
    name.set("ruby")
    println(name.get())

    println("==========通过KClass反射调用属性========")
    // 通过KClass反射调用属性
    val name2 = MyTestClass13::name
    name2.set(myTestClass13Instance,"Kotlin")
    println(name2.get(myTestClass13Instance))
}
class HelloKotlin25 {
}

26 查找一个用作Kotlin属性的getter的幕后字段或Java方法

/**
 * 查找一个用作Kotlin属性的getter的幕后字段或Java方法
 */
class MyTestClass14 {
    var name: String = "java"
    val price: Double = 34.5
}
var myTest = "myTest"

fun main() {
    val topProp = ::myTest
    println(topProp.javaField)
    println(topProp.javaSetter)
    println(topProp.javaGetter)

    val n = MyTestClass14::name
    println(n.javaField)
    println(n.javaSetter)
    println(n.javaGetter)

    val p = MyTestClass14::price
    println(p.javaField)
    println(p.javaGetter)
}
class HelloKotlin26 {
}
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-09-26 10:17:52  更:2021-09-26 10:20:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/24 13:58:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码