深入kotlin - KClass 特性深入研究
Posted 颐和园
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入kotlin - KClass 特性深入研究相关的知识,希望对你有一定的参考价值。
KClass 特性深入研究
kotlin 反射 vs. Java 反射
其实可以通过 KClass 获取属性的 java 特性,比如获得 get/set 方法和 field 的引用:
class T(val x:Int)
fun main(args: Array<String>)
println(T::x) // 打印:val com.kotlin.T.x: kotlin.Int
println(T::x.javaGetter) // 打印:public final int com.kotlin.T.getX()
println(T::x.javaField) // 打印:private final int com.kotlin.T.x
javaGetter 打印的是对应的 java 字节码的 getter 方法 - 即 java 反射中的Method 对象,javaField 打印的是 java 的 back field - 即 java 反射中的 Field。
也可以通过 java 类获得对应的 kotlin 类:
println(T(10).javaClass) // KClass -> Java Class,打印:class com.kotlin.T
println(T(10).javaClass.kotlin) // Java Class -> KClass,打印: class com.kotlin.T
这里二者打印的结果实际上是一样的。这是因为 T 本身就是一个自定义的 kotlin 类,它的 kotlin 类和 java 类是一样的。如果是一个 java 类则打印的结果又会不同:
println(String.javaClass) // 打印:class kotlin.jvm.internal.StringCompanionObject
println(String.javaClass.kotlin) // 打印:class kotlin.String$Companion
StringCompanionObject 和 String$Companion 都是伴生对象。
KClass 的两种引用方式
无论通过类还是实例引用的 KClass,都没有任何区别:
fun main(args: Array<String>)
val kotlinLang = "kotlin"
val kclass: KClass<out String> = kotlinLang::class
println(kclass) // 打印:class kotlin.String
val kclass1: KClass<String> = String::class
println(kclass1) // 打印:class kotlin.String
无论类有多少个实例,所有实例都对应唯一的 KClass 对象:
fun main(args: Array<String>)
val kc1: KClass<out String> = "kotlin"::class
val kc2: KClass<out String> = "java"::class
val kc3: KClass<out String> = "ruby"::class
println(kc1) // 打印:class kotlin.String
println(kc2) // 打印:class kotlin.String
println(kc3) // 打印:class kotlin.String
println( kc1 == kc2) // 打印:true
println( kc1 == kc3) // 打印:true
从 java 类获取 KClass
从一个 java class 获取 KClass:
val kc = Class.forName("java.util.Date").kotlin
println(kc) // 打印: class java.util.Date
println(kc == Class.forName("java.util.Date")) // 打印:false
println(kc == Class.forName("java.util.Date").kotlin) // 打印:true
可以看到,虽然 KClass 和 java class 的打印结果一样(都是 java.util.Date),但二者实质上仍然是不同的实例。
反射父类
通过 KClass 可以通过 superclasses 反射所有父类/接口的信息:
interface MyInterface
class MyClass: Serializable, MyInterface
fun main(args:Array<String>)
val kc = MyClass::class
println(kc.superclasses) // 打印:[class java.io.Serializable, com.kotlin.MyInterface, class kotlin.Any]
反射成员属性
通过 memberProperties 可以反射成员属性:
class MyClass(var a: String, val b: Boolean)
fun main(args:Array<String>)
val kc = MyClass::class
println(kc.memberProperties) // 打印:[var com.kotlin.MyClass.a:kotlin.String, val com.kotlin.MyClass.b:kotlin.Boolean]
反射成员函数
class MyClass
fun printSomething()
println("something")
fun printNothing()
println("")
fun main(args:Array<String>)
val kc = MyClass:class
println(kc.memberFunctions)
反射构造函数
class MyClass(value: Int)
constructor(amount: Int, color: String): this(amount)
println("次要构造方法")
constructor(amount:Int, full: Boolean): this(amount)
println("次要构造方法")
fun printSomething()
fun main(args: Array<String>)
val kc = MyClass::class
val constructors = kc.constructors // 获取所有构造方法的 KFunction 对象
println(constructors) // 打印:[fun <init>(kotlin.Int,kotlin.String): com.kotlin.MyClass, fun <init>(kotlin.Int,kotlin.Boolean):com.kotlin.MyClass, fun <init>(kotlin.Int):com.kotlin.MyClass]
以上是关于深入kotlin - KClass 特性深入研究的主要内容,如果未能解决你的问题,请参考以下文章