参考链接
示例来自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 {
}