Kotlin扩展功能访问Java专用字段

在使用Kotlin 扩展功能时,我想访问Java的专用字段

假设我有一个JavaABCABC只有一个私人字段mPrivateField 。 我想在Kotlin中写一个扩展函数,无论出于什么原因都使用这个字段。

 public class ABC { private int mPrivateField; } 

Kotlin函数将是:

 private fun ABC.testExtFunc() { val canIAccess = this.mPrivateField; } 

我得到的错误是:

Cannot access 'mPrivateField': It is private in 'ABC'

任何方式来解决这个限制?

首先,您需要获得一个字段并使其可以在Kotlin中访问 ,例如:

 val field = ABC::class.java.getDeclaredField("mPrivateField") field.isAccessible = true 

然后,您可以从声明类的实例中通过Field#getInt将字段值读为Int ,例如:

 val it: ABC = TODO() val value = field.getInt(it) 

最后,你的扩展方法如下所示:

 private inline fun ABC.testExtFunc():Int { return javaClass.getDeclaredField("mPrivateField").let { it.isAccessible = true val value = it.getInt(this) //todo return@let value; } } 

这是不可能的设计。 扩展函数本质上是以接收者作为第一个参数的静态函数。 因此,一个扩展功能

 fun String.foo() { println(this) } 

编译成如下所示:

 public static void foo(String $receiver) { System.out.println($receiver); } 

现在很明显看到你不能访问$receiver私人成员,因为他们是私人的。

如果你真的想访问该成员,你可以使用反射,但你会失去所有的保证。

就像nhaarman建议我用反射进入有问题的领域。 具体来说,我创建了一个getter,它在所提到的类(即ABC )内部使用了反射,

Kotlin扩展功能中的私人字段可能会在2017年7月份之前无法使用

 fun ABC.testExtFunc() { val canIAccess = this.getmPrivateField() } fun ABC.getmPrivateField() : Int { val field = this.javaClass.declaredFields .toList().filter { it.name == "mPrivateField" }.first() field.isAccessible = true val value = field.get(this) return value as Int }