Kotlin 中如何从类外部调用类的私有函数

问题描述 投票:0回答:4

我想从这个类的外部调用类

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
4个回答
8
投票

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

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())

5
投票

“私有”的想法是只有你可以在你的类中调用它。如果你想“闯入”该类,则需要利用反射: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()))
    }

}

0
投票
val managerClass = Class.forName("com.api.Manager").kotlin
val managerInstance = managerClass.createInstance()
val startMethod = managerClass
    .declaredMemberFunctions
    .first { it.name == "start" }
    .also { it.isAccessible = true }
val param = 1234
startMethod.call(managerInstance, param)

0
投票

您可以通过抑制编译警告来调用任何私有函数

@Suppress(“INVISIBLE_MEMBER”,“INVISIBLE_REFERENCE”)

@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
fun callPrivateFunction() {
  com.foo.bar.privateFunction()
}
© www.soinside.com 2019 - 2024. All rights reserved.