Kotlin反射

这篇具有很好参考价值的文章主要介绍了Kotlin反射。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、反射的概念

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

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

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

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

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

反射的常见用途

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

Java Vs Kotlin
Kotlin反射

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日志文章来源地址https://www.toymoban.com/news/detail-410154.html

----------------------------- 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反射的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Kotlin精简】第6章 反射

    反射机制 是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性。 我们对比Kotlin和Java的反射类图。 1.1.1 Kotlin反射常用的数据结构 数据结构 概念及使用说明 KType 描述未擦除的类型或泛型参数等,例

    2024年02月08日
    浏览(19)
  • Kotlin基础(十一):反射和注解

    本文主要讲解kotlin反射和注解。 Kotlin文章列表 Kotlin文章列表: 点击此处跳转查看 在Kotlin中,反射是一种能够在运行时动态地获取、检查和操作类、属性、方法等结构的能力。Kotlin为反射提供了一组API,这些API允许你在运行时获取类的信息并与其交互,而不需要在编译时知道

    2024年02月14日
    浏览(22)
  • 禁止IP访问、只允许域名访问设置方法

    联网信息系统需设置只允许通过域名访问,禁止使用IP地址直接访问,建议同时采用云防护技术隐藏系统真实IP地址且只允许云防护节点IP访问服务器,提升网络安全防护能力。 修改配置文件nginx.conf,在server段里插入正则表达式,以只允许server.web.cn域名访问为例,代码如下:

    2024年02月04日
    浏览(36)
  • nginx配置不允许通过IP只允许通过域名进行访问

    在nginx.conf配置文件中加上(如果有了监听80端口的那就改为)

    2024年02月11日
    浏览(36)
  • rabbitmq设置允许外部访问

            rabbitmq默认端口为15672,用户名和密码都为guest,是不允许外部访问的.          允许外部访问设置需要操作两步:         第一步:添加其它用户,guest只能用于本机          第二步:Virtual Host允许添加的用户访问,点击下图红色部分.          spring配置

    2024年02月11日
    浏览(38)
  • 设置MySQL允许外部访问

    一、在navicat上使用本地连接,先连接上。 二、修改user表访问权限。 然后外部就可以通过账户密码访问了。 说明: 1、※ grant语法: grant 权限名(所有的权限用all) on 库名(*全部).表名(*全部) to ‘要授权的用户名’@’%’(%表示所有的IP,可以只设一个IP) identified by “

    2024年02月02日
    浏览(30)
  • 如何允许远程访问MySQL

    许多网站和应用程序一开始都将web服务器和数据库后端托管在同一台机器上。不过,随着时间的推移,这样的设置可能会变得繁琐和难以扩展。一种常见的解决方案是通过设置远程数据库来分离这些功能,允许服务器和数据库在各自的机器上按自己的速度增长。 用户在尝试建

    2024年02月10日
    浏览(34)
  • 关于C#反射概念,附带案例!

    C#中的反射是一种使程序在运行时能够动态地获取类型信息并调用其成员的技术。通过反射,程序可以在运行时进行类型的动态加载、创建对象、调用方法和属性,以及访问和修改字段等。反射可以使程序更加灵活,但也增加了一定的性能开销。 在C#中,反射主要是通过Syst

    2024年02月05日
    浏览(27)
  • 设置Redis允许使用IP访问

    问题: 可以使用127.0.0.1配置并访问使用Redis,但是换成IP地址就无法访问 解决: 打开安装目录下 redis.windows.config 文件(linux对应redis.conf文件)将 NETWORK 下 \\\" bind 127.0.0.1 \\\" 注释掉或修改为 \\\" bind 0.0.0.0 \\\" (使其他主机可以连接),并将 \\\" protected-modehou yes \\\" 改为 \\\" protected-mode no \\\"(

    2024年02月10日
    浏览(41)
  • centos设置允许访问的ip

    参考: https://www.lmlphp.com/user/64466/article/item/1159141/ https://blog.csdn.net/yangjiehuan/article/details/9253855 https://blog.csdn.net/qq_36746838/article/details/132298722 https://www.cnblogs.com/zhongguiyao/p/14082004.html 对服务器ssh登录限制: vim /etc/ssh/sshd_config 在尾部加一行(允许所有ip登录) AllowUsers root@* 或者(

    2024年02月07日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包