当前位置: 首页 > 知识库问答 >
问题:

Kotlin扩展函数访问Java专用字段

狄鹏
2023-03-14

我想在使用Kotlin扩展函数时访问Java的私有字段。

假设我有一个Java类。ABC只有一个私有字段。我想用静态编程语言编写一个扩展函数,无论出于什么原因使用该字段。

public class ABC {
    private int mPrivateField;

}

Kotlin的功能是:

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

我得到的错误是:

无法访问“mPrivateField”:它在“ABC”中是专用的

有没有办法绕过这个限制?

共有3个答案

慕嘉运
2023-03-14

使用以下扩展函数获取私有变量

fun <T : Any> T.getPrivateProperty(variableName: String): Any? {
    return javaClass.getDeclaredField(variableName).let { field ->
        field.isAccessible = true
        return@let field.get(this)
    }
}

设置私有变量值获取变量

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

获取变量使用:

val bool = <your_class_object>.getPrivateProperty("your_variable") as String

设置和获取变量使用:

val bool = <your_class_object>.setAndReturnPrivateProperty("your_variable", true) as Boolean
val str = <your_class_object>.setAndReturnPrivateProperty("your_variable", "Hello") as String
轩辕涵亮
2023-03-14

这在设计上是不可能的。扩展函数本质上分解为静态函数,接收器是其第一个参数。因此,扩展函数

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

编译成如下内容:

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

现在很明显,您无法访问$receiver的私有成员,因为它们是私有的。

如果您确实想访问该成员,可以使用反射来访问,但您将失去所有保证。

邢飞白
2023-03-14

首先,您需要获取一个Field并启用它可以在静态编程语言中访问,例如:

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;
    }
}
 类似资料:
  • 我在Kotlin文件中定义了扩展函数。 其中是(生成的)java类。现在,我想用正常的java代码访问它: 然而,那是行不通的。IDE将无法识别方法,编译失败。

  • 问题内容: 是否可以从Java代码访问扩展功能? 我在Kotlin文件中定义了扩展功能。 (生成的)java类在哪里。现在,我想用普通的Java代码访问它: 但是,这不起作用。 IDE无法识别该方法,并且编译失败。 起作用的是与kotlin的静态函数一起使用: 通过使用我的IDE似乎已正确配置。 我从kotlin文档中搜索了整个Java互操作文件,并且在谷歌上搜索了很多,但是找不到。 我究竟做错了

  • 静态编程语言全局函数: 用java调用此函数: 它会给出以下错误:无法解析方法'show WarningDialog(com.us.stickermaker.backgroundRemover.##################################################################################################### 该

  • 我在Kotlin编程,我有日期类的扩展功能。 它在< code>onCreate中工作正常,但是在< code >异步任务中的< code>doInBackground中出现错误 我里面有这些线 < code > getCurrentDateTime()返回< code>Date类的实例,并且为< code>toString()中的参数给出了错误 也可以参数为公共开放的乐趣toString():字

  • 有可能从Java代码中访问扩展函数吗? 我在静态编程语言文件中定义了扩展函数。 其中MyModel是(生成的)java类。现在,我想在我的普通java代码中访问它: 然而,那是行不通的。IDE无法识别bar()方法,编译失败。 work使用kotlin的静态函数: 通过使用导入com.test.extensions.ExtensionsPackage我的IDE似乎配置正确。 我从kotlin文档中

  • 主要内容:扩展函数,扩展函数是静态解析的,伴生对象的扩展,扩展的作用域,扩展声明为成员Kotlin 可以对一个类的属性和方法进行扩展,且不需要继承或使用 Decorator 模式。 扩展是一种静态行为,对被扩展的类代码本身不会造成任何影响。 扩展函数 扩展函数可以在已有类中添加新的方法,不会对原类做修改,扩展函数定义形式: receiverType:表示函数的接收者,也就是函数扩展的对象 functionName:扩展函数的名称 params:扩展函数的参数,可以为NULL 以下实