还可以直接通过函数引用获取 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
这里的话主要注意这个this运行时是实际的子类型(OO多态),所以最后是可以直接强转的。
上面代码是只有一个父类,如果有多个父类,会有问题,需要修改一下:
abstract class SuperType {
val typeParameter2 by lazy {
//实际中,如果子类是open可继承的可能还会有子类,具体要看使用的类
//此时需要找到合适的父类再操作,