enum class Command(private vararg val commands: String) {
@FieldEnrich("changeLanguages", "commands")
CHANGE_LANGUAGE;
}
enum class CreatingCarStep(private vararg val values: String) : AbstractStep<CreatingCarStep> {
@FieldEnrich("brand-name", "values")
BRAND_NAME {
override fun next() = MODEL
override fun previous() = BRAND_NAME
};
}
我有兩個帶有 vararg 屬性和 @FieldEnrich 注釋的列舉。
注釋看起來像
@Target(FIELD, CLASS)
@Retention(RUNTIME)
annotation class FieldEnrich(
val property: String,
val field: String
)
注釋是按物件處理的
object FieldEnricher {
lateinit var configurationProvider: ConfigurationProvider
fun enrichClass(clazz: Class<*>) {
clazz.enumConstants.forEach {
enrichField(it, clazz)
}
}
private fun enrichField(enum: Any, clazz: Class<*>) {
val enumClass = enum::class.java
if (enumClass.isAnnotationPresent(FieldEnrich::class.java)) {
val fieldEnrich = enumClass.getAnnotation(FieldEnrich::class.java)
val values = configurationProvider.getProperty(fieldEnrich.property, Array<String>::class.java)
val field = clazz.declaredFields.firstOrNull { it.name == fieldEnrich.field }
field?.isAccessible = true
field?.set(enum, values)
}
}
}
邏輯如下。我們使用注解@FieldEnrich 對列舉成員進行注解,并傳遞我們要從中讀取值的屬性以及我們設定屬性值的欄位的名稱。
我在除錯時發現它嘗試處理 CreatingCarStep 列舉是可以的,因為 enumConstants 方法回傳列舉值的實際物件。所以我可以只取這個值的類,得到這個列舉的實際類,然后用我的方法enrichField處理它。但是當它試圖處理命令列舉時,我得到的只是列舉值。所以如果我們取列舉值的類,就會回傳同一個類的Command。在此處輸入影像描述。
命令影像 -> 在此處輸入影像描述
創建CarStep 影像 -> 在此處輸入影像描述
uj5u.com熱心網友回復:
它之所以有效,是CreatingCarStep因為它的列舉常量有一個非空的主體。這迫使 kotlin 編譯器為每個列舉常量創建列舉類的子類。此外,列舉常量上的注釋將放在生成的子類上。因此,enum::class.java計算一個Class<*>實體,該實體表示CreatingCarStep具有FieldEnrich注釋的子類。
當列舉常量的主體為空或根本沒有主體時,不會生成子類。列舉常量是列舉類本身的實體。因此,enum::class.java計算結果為Command::class.java,沒有FieldEnrich注釋。
clazz.enumConstants與其獲取和獲取它們的注釋,不如獲取::class.java列舉常量欄位的注釋。這樣,您就不必依賴列舉常量是否有空體。
fun enrichClass(clazz: Class<*>) {
clazz.declaredFields.forEach {
if (it.isEnumConstant) {
enrichField(it, clazz)
}
}
}
private fun enrichField(enumField: Field, clazz: Class<*>) {
if (enumField.isAnnotationPresent(FieldEnrich::class.java)) {
val fieldEnrich = enumField.getAnnotation(FieldEnrich::class.java)
val values = configurationProvider.getProperty(fieldEnrich.property, Array<String>::class.java)
val field = clazz.declaredFields.firstOrNull { it.name == fieldEnrich.field }
field?.isAccessible = true
field?.set(enumField.get(null), values)
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/479639.html
