Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin—反射是否应该用于Java类中的合成属性_Java_Kotlin - Fatal编程技术网

Kotlin—反射是否应该用于Java类中的合成属性

Kotlin—反射是否应该用于Java类中的合成属性,java,kotlin,Java,Kotlin,考虑以下Java类: 公共最终类示例{ 私有int值; 公共int getExampleValue{ 返回值; } 公共void setExampleValue(int值){ 这个值=值; } } Kotlin将这些get/set访问器方法合成为一个属性: val-example=example() example.exampleValue=0//setExampleValue(0); val exampleValue=example.exampleValue//getExampleValue

考虑以下Java类:

公共最终类示例{
私有int值;
公共int getExampleValue{
返回值;
}
公共void setExampleValue(int值){
这个值=值;
}
}
Kotlin将这些get/set访问器方法合成为一个属性:

val-example=example()
example.exampleValue=0//setExampleValue(0);
val exampleValue=example.exampleValue//getExampleValue();
但是,Kotlin中的反射不会返回合成属性:


Example::class.memberProperties/[]Kotlin编译器不会使用实际为此声明的
exampleValue
属性合成其他包装类。它只是将属性访问语法转换为getter/setter方法调用

实际上,这种情况甚至发生在Kotlin中声明的类上。 因为这个简单的类:

E类{
公共var值=1
}
编译为与此java类不同的字节码:

公共期末考试E级{
公共int值=1;
}
但这是:

公共期末考试E级{
私有int值=1;
public int getValue(){
返回值;
}
公共无效设置值(int值){
这个值=值;
}
}
因此,当您执行
.value
时,它实际上不是字段访问,而是getter调用

Kotlin反射不会显示
exampleValue
字段,因为它不存在。 是的,您可以使用属性访问语法访问它,但这只是一个编译器技巧

如果希望通过反射获得这些“短暂属性”,则需要对编译器的技巧进行反向工程:

val getterMethodRegex=“^get\\p{Lu}.*.toRegex()//以“get”开头,后跟大写字母
示例::class.declaredFunctions.filter{it.name.matches(getterMethodRegex)}
但是,这仅适用于用Java声明的类。对于在Kotlin中声明的类,编译器不会盲目地用调用名为“尊敬的getter”的方法来替换属性访问,而是事先检查是否存在这样的属性:

class-ExampleKt{
私有值=0
fun getExampleValue()=值
}
ExampleKt().exampleValue//编译错误:“未解析的引用:exampleValue”

有趣的是,我无法在JDK 14和Kotlin 1.4上复制。10@Sweeper在您的情况下会发生什么?我得到了预期的
[var Example.value:kotlin.Int]
。我的机器上没有JDK 8,所以我不知道它是否是一个版本problem@Sweeper我很好奇它在JDK14上工作(以及为什么它在JDK14上工作)。也许我遗漏了什么。我也用JDK 11重新测试了它,但仍然得到了相同的行为。它不太“有效”,因为IIUC,您期望的是
[var Example.exampleValue:kotlin.Int]
。Sweeper获得的是字段的名称而不是属性。