Java/Android/Kotlin:在私有字段上倒影,并在其上调用公共方法

是否可以使用反射来访问对象的私有字段并在此字段上调用公共方法?

class Hello {
   private World word
}

class World {
   public BlaBlaBla foo()
}

Hello h = new Hello()

World world = reflect on the h


// And then 

world.foo()

答案 1

可以使用反射来创建字段。以下示例(均用 Kotlin 编写)显示了这一点...privateaccessible

使用 Java Reflection:

val hello = Hello()
val f = hello::class.java.getDeclaredField("world")
f.isAccessible = true
val w = f.get(hello) as World
println(w.foo())

使用 Kotlin 反射:

val hello = Hello()
val f = Hello::class.memberProperties.find { it.name == "world" }
f?.let {
    it.isAccessible = true
    val w = it.get(hello) as World
    println(w.foo())
}

答案 2

要访问 Kotlin 中某个类的私有属性和函数,这里有两个有用的扩展函数:

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

使用示例:

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

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

implementation “org.jetbrains.kotlin:kotlin-reflect:$kotlin_version”


推荐