要想使用反射,首先需要添加依赖,下面是maven中的依赖:
org.jetbrains.kotlinkotlin-reflect
根据类获得Class引用
class A
funmain(){var kClass = A::classprintln(kClass)// kclassprintln(kClass.java)// class of java languagevar stringClass = String::classprintln(stringClass)// class kotlin.Stringprintln(stringClass.java)// class java.lang.String}
根据对象获得Class引用
class B
funmain(){var b =B()println(b::class)println(b::class.java)}
方法引用
全局方法引用:
funisOdd(x: Int)= x %2!=0funmain(){val numbers =listOf(1,2,3)println(numbers.filter{isOdd(it)})println("------------")println(numbers.filter(::isOdd))}
支持重载,能根据上下文推导出参数的类型:
funisOdd(x: Int)= x %2!=0funisOdd(s: String)= s =="bob"|| s =="tom"|| s =="tina"funmain(){val numbers =listOf(1,2,3)println(numbers.filter{isOdd(it)})println("------------")println(numbers.filter(::isOdd))val strings =listOf("morris","bob","jack")println(strings.filter(::isOdd))}
成员方法引用:
funmain(){val strings =listOf("morris","bob","jack")println(strings.map(String::length))}
函数组合
funmain(){funcompose(f:(B)-> C, g:(A)-> B):(A)-> C {return{ it ->f(g(it))}}funisOdd(a: Int)= a %2==0val strings =listOf("morris","bob","jack")println(strings.map(compose(::isOdd, String::length)))}
属性引用
对于可变属性,属性引用返回的是KMutableProperty类型,可以对属性进行set和get。
对于只读属性,属性引用返回的是KProperty类型,只能对属性进行get。
var username ="morris"constval age =10funmain(){var kMutableProperty0 =::username
println(kMutableProperty0.name)// obtain the name of property
kMutableProperty0.set("kotlin")println(kMutableProperty0.get())// obtain the value of property by get()var kProperty0 =::age
println(kProperty0.name)println(kProperty0.get())}
要想访问类的成员属性,需要使用全限定名称:
classC(var p: Int)funmain(){var c =C(0)var kMutableProperty1 = C::p
kMutableProperty1.set(c,1024)// C.(Int)->Unit (C,Int)->Unitprintln(kMutableProperty1.get(c))// C.()->Int (C)->Int}
扩展函数的反射:
val String.firstChar: Char
get()=this[0]funmain(){println(String::firstChar.get("xyz"))}
java反射与kotlin反射的互操作
classD(var p: Int)funmain(){println(D::p.javaField)println(D::p.javaClass)println(String.javaClass)println(String.javaClass.kotlin)}
构造方法引用
classE(var p: Int)funfactory(f:(Int)-> E){var e =f(3)println(e.p)}funmain(){factory(::E)}
对象的方法和属性引用
funmain(){println(String::length.get("xyz"))println("xyz"::length.get())valget="abc"::getprintln(get(1))}
反射
获取类的基本信息
class F: Serializable
funmain(){var kClass = F::classprintln(kClass.superclasses)println(kClass.typeParameters)println(kClass.qualifiedName)println(kClass.simpleName)}
反射调用构造方法
classG(var name: String ="bob",var age: Int =18)funmain(){var kClass = G::class// 调用无参构造方法var gg = kClass.createInstance()println(gg.name)println(gg.age)// 调用带参数的构造方法var g = kClass.constructors.find{ it.parameters.size ==2}?.call("morris",19)println(g?.name)println(g?.age)}
反射调用成员方法
class H {funprintSomething(name: String){println("something: $name")}funprintNothing(){println("nothing")}}funmain(){var kClass = H::classvar h =H()
kClass.functions.find{ it.name =="printNothing"}?.call(h)var kFunction = kClass.functions.find{ it.name =="printSomething"}
kFunction?.call(h,"morris")}