簡體   English   中英

Kotlin - 反射是否適用於 Java 類中的合成屬性

[英]Kotlin - Should reflection work for synthetic properties in Java classes

考慮以下 Java class:

public final class Example {

    private int value;

    public int getExampleValue {
        return value;
    }

    public void setExampleValue(int value) {
        this.value = value;
    }
}

Kotlin 將這些 get/set 訪問器方法綜合為一個屬性:

val example = Example()
example.exampleValue = 0 // setExampleValue(0);
val exampleValue = example.exampleValue // getExampleValue();

但是,Kotlin 中的反射不會返回合成屬性:

Example::class.memberProperties // [] <- list is empty!

那么,Kotlin 不會通過反射返回合成屬性嗎?

我試過這個:

  • Kotlin 1.4.32 和 JDK 8
  • Kotlin 1.4.32 和 JDK 11

Kotlin 編譯器不會為此使用實際聲明的exampleValue屬性綜合附加包裝器 class。 它只是將屬性訪問語法轉換為 getter/setter 方法調用。

實際上,即使在 Kotlin 中聲明的類也會發生這種情況。 因為這個簡單的 class:

class E {
    public var value = 1
}

編譯為與此java class 不同的字節碼:

public final class E {
    public int value = 1;
}

但是這個:

public final class E {
    private int value = 1;

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }
}

因此,當您執行.value時,它實際上不是字段訪問,而是 getter 調用。

Kotlin 反射不會向您顯示exampleValue字段,因為它不存在。 是的,您可以使用屬性訪問語法來訪問它,但這只是一個編譯器技巧。

如果您想通過反射獲得這些“臨時屬性”,則需要對該編譯器的技巧進行逆向工程:

val getterMethodRegex = "^get\\p{Lu}.*".toRegex() //starts with 'get' followed by upper-case letter
Example::class.declaredFunctions.filter { it.name.matches(getterMethodRegex) }

但是,這僅適用於 Java 中聲明的類。 對於在 Kotlin 中聲明的類,編譯器不會盲目地將屬性訪問替換為對名為類似 getter 的方法的調用,而是事先檢查是否存在這樣的屬性:

class ExampleKt {
    private val value = 0
    fun getExampleValue() = value
}

ExampleKt().exampleValue //compilation error: 'Unresolved reference: exampleValue'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM