Kotlin反射

1、反射的概念

反射是允许程序在运行时访问程序结构的一类特性。

程序结构:类、属性、方法、接口等语法特性

Kotlin反射_第1张图片
反射的依赖:Java的JDK中本身就包含反射API,而Kotlin则是又做了一套。

所以使用Kotlin的反射时,需要引入依赖

implementation "org.jetbrains.kotlin:kotlin-reflect"

反射的常见用途

  1. 列出类型的所有属性、方法、内部类等
  2. 调用给定名称及签名的方法,或访问指定名称的属性
  3. 通过签名信息获取泛型实参的具体类型
  4. 访问运行时注解及其信息,完成注入或配置操作

Java Vs Kotlin
Kotlin反射_第2张图片

2、示例

2.1、类

class Teacher {

    var tName: String? = null
    var tSex: String? = null
    var tAge: Int = 0


    //无参构造方法
    constructor() {
        tName = "xName"
        tSex = "xSex"
        tAge = 0
    }

    //有参构造方法
    constructor(
        name: String?,
        sex: String?,
        age: Int
    ) {
        tName = name
        tSex = sex
        tAge = age
    }

    //扩展方法
    fun String.getStringLength() = this.length
    fun Int.add(year: Int): Int {
        return this + year
    }

    //扩展属性
    val String.lastChar: Char get() = this[length - 1]
    val String.firstChar: Char get() = this[0]


    //姓名
    fun setName(name: String?) {
        tName = name
    }

    fun getName() = tName

    //性别
    fun setSex(sex: String?) {
        tSex = sex
    }

    fun getSex() = tSex


    //年龄
    fun setAge(age: Int) {
        tAge = age
    }

    fun getAge() = tAge

}
fun main(){
    //类
    val kTeacher: KClass<Teacher> = Teacher::class
    testKTeacher.invoke(kTeacher)
}


val testKTeacher: (KClass<Teacher>) -> Unit = { kTeacher ->
    println("------------------------- kTeacher --------------------------")
    println("kTeacher.isAbstract:  ${kTeacher.isAbstract}")
    println("kTeacher.isData:  ${kTeacher.isData}")
    println("kTeacher.isFinal:  ${kTeacher.isFinal}")
    println("kTeacher.isCompanion:  ${kTeacher.isCompanion}")
    println("kTeacher.isFun:  ${kTeacher.isFun}")
    println("kTeacher.isInner:  ${kTeacher.isInner}")
    println("kTeacher.isOpen:  ${kTeacher.isOpen}")
    println("kTeacher.isSealed:  ${kTeacher.isSealed}")
    println("kTeacher.isValue:  ${kTeacher.isValue}")
    println("kTeacher.qualifiedName:  ${kTeacher.qualifiedName}")
    println("kTeacher.simpleName:  ${kTeacher.simpleName}")


    println("--- 类中的扩展属性 ---")
    kTeacher.declaredMemberExtensionProperties.forEach {
        println("kTeacher.declaredMemberExtensionProperties:  $it}")
    }

    println("--- 类中的扩展方法 ---")
    kTeacher.declaredMemberExtensionFunctions.forEach {
        println("kTeacher.declaredMemberExtensionFunctions:  ${it}")
    }

    println("--- declaredMemberProperties ---")
    kTeacher.declaredMemberProperties.forEach {
        println("kTeacher.declaredMemberProperties:  ${it}")
    }

    println("--- declaredFunctions ---")
    kTeacher.declaredFunctions.forEach {
        println("kTeacher.declaredFunctions:  ${it}")
    }

    println("--- declaredMembers ---")
    kTeacher.declaredMembers.forEach {
        println("kTeacher.declaredMembers:  ${it}")
    }

    println("--- declaredMemberFunctions ---")
    kTeacher.declaredMemberFunctions.forEach {
        println("kTeacher.declaredMemberFunctions:  ${it}")
    }
}

log日志

------------------------- kTeacher --------------------------
kTeacher.isAbstract:  false
kTeacher.isData:  false
kTeacher.isFinal:  true
kTeacher.isCompanion:  false
kTeacher.isFun:  false
kTeacher.isInner:  false
kTeacher.isOpen:  false
kTeacher.isSealed:  false
kTeacher.isValue:  false
kTeacher.qualifiedName:  com.example.kotlinlearning_zlz.learning.Teacher
kTeacher.simpleName:  Teacher
--- 类中的扩展属性 ---
kTeacher.declaredMemberExtensionProperties:  val com.example.kotlinlearning_zlz.learning.Teacher.(kotlin.String.)firstChar: kotlin.Char}
kTeacher.declaredMemberExtensionProperties:  val com.example.kotlinlearning_zlz.learning.Teacher.(kotlin.String.)lastChar: kotlin.Char}
--- 类中的扩展方法 ---
kTeacher.declaredMemberExtensionFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.(kotlin.Int.)add(kotlin.Int): kotlin.Int
kTeacher.declaredMemberExtensionFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.(kotlin.String.)getStringLength(): kotlin.Int
--- declaredMemberProperties ---
kTeacher.declaredMemberProperties:  var com.example.kotlinlearning_zlz.learning.Teacher.tAge: kotlin.Int
kTeacher.declaredMemberProperties:  var com.example.kotlinlearning_zlz.learning.Teacher.tName: kotlin.String?
kTeacher.declaredMemberProperties:  var com.example.kotlinlearning_zlz.learning.Teacher.tSex: kotlin.String?
--- declaredFunctions ---
kTeacher.declaredFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.getAge(): kotlin.Int
kTeacher.declaredFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.getName(): kotlin.String?
kTeacher.declaredFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.getSex(): kotlin.String?
kTeacher.declaredFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.setAge(kotlin.Int): kotlin.Unit
kTeacher.declaredFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.setName(kotlin.String?): kotlin.Unit
kTeacher.declaredFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.setSex(kotlin.String?): kotlin.Unit
kTeacher.declaredFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.(kotlin.Int.)add(kotlin.Int): kotlin.Int
kTeacher.declaredFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.(kotlin.String.)getStringLength(): kotlin.Int
--- declaredMembers ---
kTeacher.declaredMembers:  var com.example.kotlinlearning_zlz.learning.Teacher.tAge: kotlin.Int
kTeacher.declaredMembers:  var com.example.kotlinlearning_zlz.learning.Teacher.tName: kotlin.String?
kTeacher.declaredMembers:  var com.example.kotlinlearning_zlz.learning.Teacher.tSex: kotlin.String?
kTeacher.declaredMembers:  val com.example.kotlinlearning_zlz.learning.Teacher.(kotlin.String.)firstChar: kotlin.Char
kTeacher.declaredMembers:  val com.example.kotlinlearning_zlz.learning.Teacher.(kotlin.String.)lastChar: kotlin.Char
kTeacher.declaredMembers:  fun com.example.kotlinlearning_zlz.learning.Teacher.getAge(): kotlin.Int
kTeacher.declaredMembers:  fun com.example.kotlinlearning_zlz.learning.Teacher.getName(): kotlin.String?
kTeacher.declaredMembers:  fun com.example.kotlinlearning_zlz.learning.Teacher.getSex(): kotlin.String?
kTeacher.declaredMembers:  fun com.example.kotlinlearning_zlz.learning.Teacher.setAge(kotlin.Int): kotlin.Unit
kTeacher.declaredMembers:  fun com.example.kotlinlearning_zlz.learning.Teacher.setName(kotlin.String?): kotlin.Unit
kTeacher.declaredMembers:  fun com.example.kotlinlearning_zlz.learning.Teacher.setSex(kotlin.String?): kotlin.Unit
kTeacher.declaredMembers:  fun com.example.kotlinlearning_zlz.learning.Teacher.(kotlin.Int.)add(kotlin.Int): kotlin.Int
kTeacher.declaredMembers:  fun com.example.kotlinlearning_zlz.learning.Teacher.(kotlin.String.)getStringLength(): kotlin.Int
--- declaredMemberFunctions ---
kTeacher.declaredMemberFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.getAge(): kotlin.Int
kTeacher.declaredMemberFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.getName(): kotlin.String?
kTeacher.declaredMemberFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.getSex(): kotlin.String?
kTeacher.declaredMemberFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.setAge(kotlin.Int): kotlin.Unit
kTeacher.declaredMemberFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.setName(kotlin.String?): kotlin.Unit
kTeacher.declaredMemberFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.setSex(kotlin.String?): kotlin.Unit

2.2、对象

fun main(){
    //对象
    val teacherLeon = Teacher("Leon", "Man", 26)
    val kLeon: KClass<out Teacher> = teacherLeon::class
    testKLeon.invoke(kLeon)
}


val testKLeon: (KClass<out Teacher>) -> Unit = { kLeon ->

    println("------------------------- kLeon --------------------------")
    println("kLeon.isAbstract:  ${kLeon.isAbstract}")
    println("kLeon.isData:  ${kLeon.isData}")
    println("kLeon.isFinal:  ${kLeon.isFinal}")
    println("kLeon.isCompanion:  ${kLeon.isCompanion}")
    println("kLeon.isFun:  ${kLeon.isFun}")
    println("kLeon.isInner:  ${kLeon.isInner}")
    println("kLeon.isOpen:  ${kLeon.isOpen}")
    println("kLeon.isSealed:  ${kLeon.isSealed}")
    println("kLeon.isValue:  ${kLeon.isValue}")
    println("kLeon.qualifiedName:  ${kLeon.qualifiedName}")
    println("kLeon.simpleName:  ${kLeon.simpleName}")


    println("--- 类中的扩展属性 ---")
    kLeon.declaredMemberExtensionProperties.forEach {
        println("kLeon.declaredMemberExtensionProperties:  $it}")
    }

    println("--- 类中的扩展方法 ---")
    kLeon.declaredMemberExtensionFunctions.forEach {
        println("kLeon.declaredMemberExtensionFunctions:  ${it}")
    }

    println("--- declaredMemberProperties ---")
    kLeon.declaredMemberProperties.forEach {
        println("kLeon.declaredMemberProperties:  ${it}")
    }

    println("--- declaredFunctions ---")
    kLeon.declaredFunctions.forEach {
        println("kLeon.declaredFunctions:  ${it}")
    }

    println("--- declaredMembers ---")
    kLeon.declaredMembers.forEach {
        println("kLeon.declaredMembers:  ${it}")
    }

    println("--- declaredMemberFunctions ---")
    kLeon.declaredMemberFunctions.forEach {
        println("kLeon.declaredMemberFunctions:  ${it}")
    }
}

log日志

------------------------- kLeon --------------------------
kLeon.isAbstract:  false
kLeon.isData:  false
kLeon.isFinal:  true
kLeon.isCompanion:  false
kLeon.isFun:  false
kLeon.isInner:  false
kLeon.isOpen:  false
kLeon.isSealed:  false
kLeon.isValue:  false
kLeon.qualifiedName:  com.example.kotlinlearning_zlz.learning.Teacher
kLeon.simpleName:  Teacher
--- 类中的扩展属性 ---
kLeon.declaredMemberExtensionProperties:  val com.example.kotlinlearning_zlz.learning.Teacher.(kotlin.String.)firstChar: kotlin.Char}
kLeon.declaredMemberExtensionProperties:  val com.example.kotlinlearning_zlz.learning.Teacher.(kotlin.String.)lastChar: kotlin.Char}
--- 类中的扩展方法 ---
kLeon.declaredMemberExtensionFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.(kotlin.Int.)add(kotlin.Int): kotlin.Int
kLeon.declaredMemberExtensionFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.(kotlin.String.)getStringLength(): kotlin.Int
--- declaredMemberProperties ---
kLeon.declaredMemberProperties:  var com.example.kotlinlearning_zlz.learning.Teacher.tAge: kotlin.Int
kLeon.declaredMemberProperties:  var com.example.kotlinlearning_zlz.learning.Teacher.tName: kotlin.String?
kLeon.declaredMemberProperties:  var com.example.kotlinlearning_zlz.learning.Teacher.tSex: kotlin.String?
--- declaredFunctions ---
kLeon.declaredFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.getAge(): kotlin.Int
kLeon.declaredFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.getName(): kotlin.String?
kLeon.declaredFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.getSex(): kotlin.String?
kLeon.declaredFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.setAge(kotlin.Int): kotlin.Unit
kLeon.declaredFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.setName(kotlin.String?): kotlin.Unit
kLeon.declaredFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.setSex(kotlin.String?): kotlin.Unit
kLeon.declaredFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.(kotlin.Int.)add(kotlin.Int): kotlin.Int
kLeon.declaredFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.(kotlin.String.)getStringLength(): kotlin.Int
--- declaredMembers ---
kLeon.declaredMembers:  var com.example.kotlinlearning_zlz.learning.Teacher.tAge: kotlin.Int
kLeon.declaredMembers:  var com.example.kotlinlearning_zlz.learning.Teacher.tName: kotlin.String?
kLeon.declaredMembers:  var com.example.kotlinlearning_zlz.learning.Teacher.tSex: kotlin.String?
kLeon.declaredMembers:  val com.example.kotlinlearning_zlz.learning.Teacher.(kotlin.String.)firstChar: kotlin.Char
kLeon.declaredMembers:  val com.example.kotlinlearning_zlz.learning.Teacher.(kotlin.String.)lastChar: kotlin.Char
kLeon.declaredMembers:  fun com.example.kotlinlearning_zlz.learning.Teacher.getAge(): kotlin.Int
kLeon.declaredMembers:  fun com.example.kotlinlearning_zlz.learning.Teacher.getName(): kotlin.String?
kLeon.declaredMembers:  fun com.example.kotlinlearning_zlz.learning.Teacher.getSex(): kotlin.String?
kLeon.declaredMembers:  fun com.example.kotlinlearning_zlz.learning.Teacher.setAge(kotlin.Int): kotlin.Unit
kLeon.declaredMembers:  fun com.example.kotlinlearning_zlz.learning.Teacher.setName(kotlin.String?): kotlin.Unit
kLeon.declaredMembers:  fun com.example.kotlinlearning_zlz.learning.Teacher.setSex(kotlin.String?): kotlin.Unit
kLeon.declaredMembers:  fun com.example.kotlinlearning_zlz.learning.Teacher.(kotlin.Int.)add(kotlin.Int): kotlin.Int
kLeon.declaredMembers:  fun com.example.kotlinlearning_zlz.learning.Teacher.(kotlin.String.)getStringLength(): kotlin.Int
--- declaredMemberFunctions ---
kLeon.declaredMemberFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.getAge(): kotlin.Int
kLeon.declaredMemberFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.getName(): kotlin.String?
kLeon.declaredMemberFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.getSex(): kotlin.String?
kLeon.declaredMemberFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.setAge(kotlin.Int): kotlin.Unit
kLeon.declaredMemberFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.setName(kotlin.String?): kotlin.Unit
kLeon.declaredMemberFunctions:  fun com.example.kotlinlearning_zlz.learning.Teacher.setSex(kotlin.String?): kotlin.Unit

2.3、object

fun main(){
    //两句等价, 对于object类型
    D.show()
    D::class.objectInstance?.run { show() }
}


object D {
    fun show() {
        println("这是object D")
    }
}

log日志

这是object D
这是object D

2.4、父类

fun main(){
    C::class.supertypes.forEach {
        println("C的父类 $it") //B
    }
}

open class A {}

open class B : A() {}

class C : B() {}

log日志

C的父类 com.example.kotlinlearning_zlz.learning.B

2.5、KClass和KType

fun main(){
    //KClass和KType
    //KClass已被擦除,没有泛型实参
    //KType有泛型实参
    val xKClass = X::class
    println("KClass: $xKClass")
    val xKType = typeOf<X<String, Int>>()
    xKType.arguments.forEach {
        println("KType: $it")
    }
}


class X<T, R> {
    private var t: T? = null
    private var r: R? = null
}

log日志

KClass: class com.example.kotlinlearning_zlz.learning.X
KType: kotlin.String
KType: kotlin.Int

3、获取泛型实参

  • 反射之所以可以获取到泛型实参是因为 signature 中包含被泛型擦除的类型值
  • 比如, fun getList():List<'Sting>
  • 泛型擦除就只剩List, 但 signature 中保留着String, 所以反射可以从中获取到被擦除调的String
  • 代码混淆时会将 signature 混淆掉
  • 所以, 混淆策略要配置 -keepattributes Signature 防止 signature被混淆

3.1、获取接口返回值中的泛型实参 - Kotlin反射

interface Api {
    fun getList(): List<Double>
    fun getMap(): Map<String, Int>
}
/**
 * 获取接口返回值类型 - List
 */
val getInterfaceListReturnType: () -> Unit = {
    //获取到getAllTeacherInfo()方法
    val apiFunsFilter = Api::class.declaredFunctions.filter { it.name == "getList" }
    //getAllTeacherInfo()方法只有一个, 还可以使用First
    val apiFunFirst = Api::class.declaredFunctions.first { it.name == "getList" }

    println("----------------------------- apiFunsFilter -----------------------------")
    apiFunsFilter.forEach {
        println(it)
    }
    println("----------------------------- apiFunFirst -----------------------------")
    println("$apiFunFirst")


    //方法返回值
    val returnTypeFilter = apiFunsFilter[0].returnType
    val returnTypeFirst = apiFunFirst.returnType
    println("----------------------------- returnType -----------------------------")
    println("returnTypeFilter: $returnTypeFilter")
    println("returnTypeFirst: $returnTypeFirst")

    //返回值的Arguments
    val returnTypeArgumentsFilter = returnTypeFilter.arguments
    val returnTypeArgumentsFirst = returnTypeFirst.arguments
    println("----------------------------- returnTypeArgumentsFilter -----------------------------")
    returnTypeArgumentsFilter.forEach {
        println(it)
    }
    println("----------------------------- returnTypeArgumentsFirst -----------------------------")
    returnTypeArgumentsFirst.forEach {
        println(it)
    }


    //引用
    println("----------------------------- 引用类型Api::getList获取KFunction -----------------------------")
    Api::getList.returnType.arguments.forEach {
        println(it)
    }
}
/**
 * 获取接口返回值类型 - Map
 */
val getInterfaceMapReturnType: () -> Unit = {

    val apiFun = Api::class.declaredFunctions.first { it.name == "getMap" }

    val returnType = apiFun.returnType

    val returnTypeArguments = returnType.arguments


    println("----------------------------- apiFun -----------------------------")
    println("$apiFun")
    println("----------------------------- returnType -----------------------------")
    println("$returnType")
    println("----------------------------- returnTypeArguments -----------------------------")
    returnTypeArguments.forEach {
        println(it)
    }


    //引用
    println("----------------------------- 引用类型Api::getMap获取KFunction -----------------------------")
    Api::getMap.returnType.arguments.forEach {
        println(it)
    }
}
fun main(){
    //获取接口返回值类型 - kotlin
    getInterfaceListReturnType.invoke()
    getInterfaceMapReturnType.invoke()
}

log日志

----------------------------- apiFunsFilter -----------------------------
fun com.example.kotlinlearning_zlz.learning.Api.getList(): kotlin.collections.List<kotlin.Double>
----------------------------- apiFunFirst -----------------------------
fun com.example.kotlinlearning_zlz.learning.Api.getList(): kotlin.collections.List<kotlin.Double>
----------------------------- returnType -----------------------------
returnTypeFilter: kotlin.collections.List<kotlin.Double>
returnTypeFirst: kotlin.collections.List<kotlin.Double>
----------------------------- returnTypeArgumentsFilter -----------------------------
kotlin.Double
----------------------------- returnTypeArgumentsFirst -----------------------------
kotlin.Double
----------------------------- 引用类型Api::getList获取KFunction -----------------------------
kotlin.Double
----------------------------- apiFun -----------------------------
fun com.example.kotlinlearning_zlz.learning.Api.getMap(): kotlin.collections.Map<kotlin.String, kotlin.Int>
----------------------------- returnType -----------------------------
kotlin.collections.Map<kotlin.String, kotlin.Int>
----------------------------- returnTypeArguments -----------------------------
kotlin.String
kotlin.Int
----------------------------- 引用类型Api::getMap获取KFunction -----------------------------
kotlin.String
kotlin.Int

3.2、获取接口返回值中的泛型实参 - Java反射

/**
 * 获取接口返回值类型 - java
 */
val getInterfaceReturnTypeJava: () -> Unit = {

    val javaMethod = Api::class.java.getDeclaredMethod("getMap")

    val javaReturnType = javaMethod.genericReturnType.safeAs<ParameterizedType>()

    val javaReturnTypeArguments = javaReturnType!!.actualTypeArguments


    println("----------------------------- javaMethod -----------------------------")
    println(javaMethod)
    println("----------------------------- javaReturnType -----------------------------")
    println(javaReturnType)
    println("----------------------------- javaReturnTypeArguments -----------------------------")
    javaReturnTypeArguments.forEach {
        println(it)
    }

}
fun main(){
    //获取接口返回值类型 - java
    getInterfaceReturnTypeJava.invoke()
}

log日志

----------------------------- javaMethod -----------------------------
public abstract java.util.Map com.example.kotlinlearning_zlz.learning.Api.getMap()
----------------------------- javaReturnType -----------------------------
java.util.Map<java.lang.String, java.lang.Integer>
----------------------------- javaReturnTypeArguments -----------------------------
class java.lang.String
class java.lang.Integer

3.3、在父类中获取子类的泛型实参,在子类中获取泛型实参

父类

/**
 * 在父类中获取子类的泛型实参
 */
abstract class Father<T, R> {

    val sonRealParamTypeKotlin by lazy {
        //因为Father是抽象类, 所以此处的this一定是子类的this
        val superTypes = this::class.supertypes
        val superTypesArguments = superTypes[0].arguments

        val type = this::class.allSupertypes.first().arguments.first().type //String

        println("----------------------------- superTypes Father -----------------------------")
        superTypes.forEach {
            println(it)
        }
        println("----------------------------- superTypeArguments Father -----------------------------")
        superTypesArguments.forEach {
            println(it)
        }
        println("----------------------------- superTypeArguments type Father -----------------------------")
        println(type)

        "父类中获取泛型实参 Kotlin  Son"
    }


    val sonRealParamTypeJava by lazy {
        val superTypes = this::class.java.genericSuperclass

        val superTypesArguments = superTypes.safeAs<ParameterizedType>()!!.actualTypeArguments

        println("----------------------------- superTypes Father Java-----------------------------")
        println(superTypes)
        println("----------------------------- superTypeArguments Father Java-----------------------------")
        superTypesArguments.forEach {
            println(it)
        }

        "父类中获取泛型实参 Java  Son"
    }


    val grandSonRealParamTypeKotlin by lazy {

        val superTypes = this::class.supertypes
        val allSuperTypes = this::class.allSupertypes

        val allSuperTypesFirst = allSuperTypes.first()//Son
        val allSuperTypesFirstArguments = allSuperTypesFirst.arguments //空列表
//        val allSuperTypesFirstArgumentsFirstType = allSuperTypesFirst.arguments.first().type

        println("----------------------------- superTypes Father GrandSon -----------------------------")
        superTypes.forEach {
            println(it)
        }

        println("----------------------------- allSuperTypes Father GrandSon -----------------------------")
        allSuperTypes.forEach {
            println(it)
        }

        println("----------------------------- allSuperTypesFirst Father GrandSon -----------------------------")
        println(allSuperTypesFirst)

        println("----------------------------- allSuperTypesFirstArguments Father GrandSon -----------------------------")
        allSuperTypesFirstArguments.forEach {
            println(it)
        }

//        println("----------------------------- allSuperTypesFirstArgumentsFirstType Father GrandSon -----------------------------")
//        println(allSuperTypesFirstArgumentsFirstType)

        "父类中获取泛型实参 Kotlin  GrandSon"
    }


}

子类

open class Son : Father<String, Float>() {


    //子类中获取父类的泛型实参很容易
    fun displayParamType() {
        val superTypes = this::class.supertypes
        val superTypesArguments = superTypes[0].arguments


        println("----------------------------- superTypes Son-----------------------------")
        superTypes.forEach {
            println(it)
        }
        println("----------------------------- superTypesArguments Son -----------------------------")
        superTypesArguments.forEach {
            println(it)
        }
    }

}

孙类

class GrandSon : Son() {}
fun main(){
    val son = Son()
    son.sonRealParamTypeKotlin.let(::println)
    son.sonRealParamTypeJava.let(::println)
    son.displayParamType()

    val grandSon = GrandSon()
    grandSon.grandSonRealParamTypeKotlin.let(::println)
}

log日志

----------------------------- superTypes Father -----------------------------
com.example.kotlinlearning_zlz.learning.Father<kotlin.String, kotlin.Float>
----------------------------- superTypeArguments Father -----------------------------
kotlin.String
kotlin.Float
----------------------------- superTypeArguments type Father -----------------------------
kotlin.String
父类中获取泛型实参 Kotlin  Son
----------------------------- superTypes Father Java-----------------------------
com.example.kotlinlearning_zlz.learning.Father<java.lang.String, java.lang.Float>
----------------------------- superTypeArguments Father Java-----------------------------
class java.lang.String
class java.lang.Float
父类中获取泛型实参 Java  Son
----------------------------- superTypes Son-----------------------------
com.example.kotlinlearning_zlz.learning.Father<kotlin.String, kotlin.Float>
----------------------------- superTypesArguments Son -----------------------------
kotlin.String
kotlin.Float
----------------------------- superTypes Father GrandSon -----------------------------
com.example.kotlinlearning_zlz.learning.Son
----------------------------- allSuperTypes Father GrandSon -----------------------------
com.example.kotlinlearning_zlz.learning.Son
com.example.kotlinlearning_zlz.learning.Father<kotlin.String, kotlin.Float>
kotlin.Any
----------------------------- allSuperTypesFirst Father GrandSon -----------------------------
com.example.kotlinlearning_zlz.learning.Son
----------------------------- allSuperTypesFirstArguments Father GrandSon -----------------------------
父类中获取泛型实参 Kotlin  GrandSon

你可能感兴趣的:(Kotlin,Learning,kotlin,android,java)