【问题标题】:How to call private functions of a class from outside the class in Kotlin如何从 Kotlin 中的类外部调用类的私有函数
【发布时间】:2019-12-17 09:12:44
【问题描述】:

我想从这个类之外调用类SomeClass的私有函数:

class SomeClass {
    private fun somePrivateFunction() {
        //...
    }

    private fun somePrivateFunctionWithParams(text: String) {
        //...
    }
}

在代码中的某处我引用了SomeClass 对象:

val someClass = SomeClass()
// how can I call the private function `somePrivateFunction()` from here?
// how can I call the private function `somePrivateFunctionWithParams("some text")` from? here

如何在 Kotlin 中从类外调用带参数和不带参数的私有函数?

【问题讨论】:

    标签: kotlin reflection private private-methods private-functions


    【解决方案1】:

    “私人”的想法是只有你可以在你的课堂上调用它。如果您想“闯入”该课程,则需要使用反射:https://stackoverflow.com/a/48159066/8073652

    来自文档:

    private 表示仅在该类内部可见(包括其所有成员)

    这是一个例子:

    class WithPrivate {
        private fun privFun() = "you got me"
    }
    
    fun main() {
        WithPrivate::class.declaredMemberFunctions.find { it.name == "privFun" }?.let {
            it.isAccessible = true
            println(it.call(WithPrivate()))
        }
    
    }
    

    【讨论】:

    • 我认为 OP 想知道如何使用反射来做到这一点,但问题中唯一的暗示是反射标签......
    • 通过您提供的链接,我看到了如何访问对象的私有字段,但没有关于如何调用对象的私有函数的信息。
    • 添加了一个函数的例子,虽然很相似
    【解决方案2】:

    我遇到了两个有用的扩展函数,它们使用反射:

    inline fun <reified T> T.callPrivateFunc(name: String, vararg args: Any?): Any? =
        T::class
            .declaredMemberFunctions
            .firstOrNull { it.name == name }
            ?.apply { isAccessible = true }
            ?.call(this, *args)
    
    inline fun <reified T : Any, R> T.getPrivateProperty(name: String): R? =
        T::class
            .memberProperties
            .firstOrNull { it.name == name }
            ?.apply { isAccessible = true }
            ?.get(this) as? R
    

    要在 Kotlin 中使用反射,请添加依赖项:

    实现“org.jetbrains.kotlin:kotlin-reflect:$kotlin_version”

    这些函数可以如下使用:

    class SomeClass {
    
        private val world: World = World()
    
        private fun somePrivateFunction() {
            println("somePrivateFunction")
        }
    
        private fun somePrivateFunctionWithParams(text: String) {
            println("somePrivateFunctionWithParams()  text=$text")
        }
    }
    
    class World {
        fun foo(): String = "Test func"
    }
    
    // calling private functions:
    
    val someClass = SomeClass()
    someClass.callPrivateFunc("somePrivateFunction")
    someClass.callPrivateFunc("somePrivateFunctionWithParams", "test arg")
    
    // getting private member and calling public function on it:
    
    val world = someClass.getPrivateProperty<SomeClass, World>("world")
    println(world?.foo())
    

    【讨论】:

      猜你喜欢
      • 2011-12-29
      • 1970-01-01
      • 1970-01-01
      • 2012-07-02
      • 2021-02-18
      • 1970-01-01
      • 2014-12-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多