class a {
fun string.hello(){
this 表示当前string对象
this@a 表示外部当前的class a对象
}
}
java也是一样,内部类获取外部类的实例时需要通过,a.this
获取
获取泛型实参:
1.获取接口某个方法的返回值类型的泛型参数
interface api {
fun getusers(): list
}
获取上面 api 接口的 getusers() 返回类型的泛型参数类 userdto
有几种方式,第一种是根据name来比较判断找到对应的方法:
//获取到 api的getusers() 方法 通过 filter
val functions = api::class.declaredfunctions.filter { it.name == “getusers” }
val getusers : kfunction<*> = functions.get(0)
getusers.returntype.arguments.foreach {
println(“getuser的返回值泛型:${it}”)
}
//获取函数的返回值参数的泛型类型userdto 通过 first
api::class.declaredfunctions.first { it.name == “getusers” }
.returntype.arguments.foreach {
println(“getuser的返回值泛型:${it}”)
}
还可以直接通过函数引用获取 api::getusers
得到的就是一个kfunction
api::getusers.returntype.arguments.foreach {
println(“getuser的返回值泛型2:${it}”)
}
显然这种方式最简单了。
还可以通过java的反射方式来获取:
//api::class.java是获取到对应java的class class 然后可以调用java的反射方法获取泛型类型
api::class.java.getdeclaredmethod(“getusers”)
.genericreturntype.safeas()?.actualtypearguments?.foreach {
println(it)
}
//safeas是定义的一个any的扩展方法
fun any.safeas(): t? {
return this as? t
}
//safeas扩展方法可以简写下面的代码,等价于上面的代码
(api::class.java.getdeclaredmethod(“getusers”)
.genericreturntype as parameterizedtype).actualtypearguments?.foreach {
println(it)
}
只能说java的方式也可以,但是这种也太麻烦了。。还是全部用kotlin的方法吧,不然得各种强转各种判空?.
2.获取接口类的泛型
abstract class supertype {
//kotlin反射方法获取
val typeparameter by lazy {
//this是实际运行子类型, supertypes拿到父类型,first是第一个父类型即supertype,arguments获取到泛型参数列表,只有一个可以first(),
// first()方法返回的是ktypeprojection,ktypeprojection.type才返回ktype
this::class.supertypes.first().arguments.first().type!!
}
//java反射方法获取
val typeparameterjava by lazy {
this.javaclass.genericsuperclass.safeas()!!.actualtypearguments.first()
}
}
open class subtype : supertype()
获取上面 subtype类实现的supertype接口类的泛型:
val subtype = subtype()
subtype.typeparameter.let(::println) // kotlin.string
subtype.typeparameterjava.let(::println) // class java.lang.string java获取的永远是java类型的描述
关键代码就是这句:this::class.supertypes.first().arguments.first().type</
发表评论