kos*_*cki 20 kotlin kotlin-extension kotlin-interop
我想在使用Kotlin 扩展功能时访问Java的私有字段.
假设我有一个Java类ABC.ABC只有一个私人领域mPrivateField.我想在Kotlin中编写一个扩展函数,无论出于何种原因使用该字段.
public class ABC {
private int mPrivateField;
}
Run Code Online (Sandbox Code Playgroud)
在科特林功能是:
private fun ABC.testExtFunc() {
val canIAccess = this.mPrivateField;
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误是:
Cannot access 'mPrivateField': It is private in 'ABC'
有什么办法解决这个限制?
hol*_*ava 26
首先,您需要获取一个Field并使其可以在Kotlin中访问,例如:
val field = ABC::class.java.getDeclaredField("mPrivateField")
field.isAccessible = true
Run Code Online (Sandbox Code Playgroud)
然后,您可以从声明类的实例中Int通过Field#getInt读取字段值,例如:
val it: ABC = TODO()
val value = field.getInt(it)
Run Code Online (Sandbox Code Playgroud)
最后,您的扩展方法如下所示:
private inline fun ABC.testExtFunc():Int {
return javaClass.getDeclaredField("mPrivateField").let {
it.isAccessible = true
val value = it.getInt(this)
//todo
return@let value;
}
}
Run Code Online (Sandbox Code Playgroud)
akh*_*707 14
使用以下扩展函数获取私有变量
fun <T : Any> T.getPrivateProperty(variableName: String): Any? {
return javaClass.getDeclaredField(variableName).let { field ->
field.isAccessible = true
return@let field.get(this)
}
}
Run Code Online (Sandbox Code Playgroud)
设置私有变量值获取变量
fun <T : Any> T.setAndReturnPrivateProperty(variableName: String, data: Any): Any? {
return javaClass.getDeclaredField(variableName).let { field ->
field.isAccessible = true
field.set(this, data)
return@let field.get(this)
}
}
Run Code Online (Sandbox Code Playgroud)
获取变量使用:
val bool = <your_class_object>.getPrivateProperty("your_variable") as String
Run Code Online (Sandbox Code Playgroud)
设置和获取变量使用:
val bool = <your_class_object>.setAndReturnPrivateProperty("your_variable", true) as Boolean
val str = <your_class_object>.setAndReturnPrivateProperty("your_variable", "Hello") as String
Run Code Online (Sandbox Code Playgroud)
这在设计上是不可能的.扩展函数基本上解析为静态函数,接收器作为其第一个参数.因此,扩展功能
fun String.foo() {
println(this)
}
Run Code Online (Sandbox Code Playgroud)
编译成如下:
public static void foo(String $receiver) {
System.out.println($receiver);
}
Run Code Online (Sandbox Code Playgroud)
现在很明显看到你无法访问私人成员$receiver,因为他们是私有的.
如果你真的想要访问该成员,你可以使用反射,但你将失去所有保证.
| 归档时间: |
|
| 查看次数: |
9478 次 |
| 最近记录: |