Я использую аннотацию Firestore на основе Java для маркировки полей и методы для сопоставления полей документа с элементами класса Java:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD})
public @interface PropertyName {
String value();
}
Я использую его для поля в классе данных Kotlin, который хорошо компилируется:
data class MyDataClass(
@PropertyName("z") val x: Int
)
В IntelliJ и Android Studio я вижу это в декомпилированном дампе класса:
public final data class MyDataClass public constructor(x: kotlin.Int) {
@field:com.google.cloud.firestore.annotation.PropertyName public final val x: kotlin.Int /* compiled code */
public final operator fun component1(): kotlin.Int { /* compiled code */ }
}
На данный момент у меня сложилось впечатление, что эту аннотацию нужно как-то обнаружитьчерез котлинское отражение.Насколько я могу сказать, это не так.Я пытался повторить аннотации:
- Каждое поле конструктора класса данных Kotlin
- Каждое поле Kotlin
- Каждая функция Kotlin
- Каждая JavaКонструктор
- Каждое поле Java
- Каждый метод Java
Он просто нигде не отображается.
В тот момент, когда я изменяю использованиеаннотация, подобная этой (обратите внимание на целевой спецификатор "get" сейчас):
data class MyDataClass(
@get:PropertyName("z") val x: Int
)
Аннотация теперь отображается в сгенерированном геттере объекта класса Java.Это, по крайней мере, на практике, но мне любопытно, почему Kotlin позволяет мне скомпилировать аннотацию в виде аннотации с таргетингом на поле, но не позволяет вернуть ее обратно во время выполнения (если я не пропустил что-то вAPI-интерфейсы kotlin-рефлекса?).
Если я вместо этого использую эту аннотацию на основе Kotlin:
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.PROPERTY)
annotation class PropertyName(val value: String)
При этом аннотация появляется во время выполнения на поле Kotlin.Это любопытно, потому что ElementType.FIELD в Java просто не может идеально отображаться в AnnotationTarget.FIELD Котлина.
(Кстати, если я изменю это на AnnotationTarget.VALUE_PARAMETER, я также могу обнаружить эту аннотацию в конструкторе класса данныхпараметр.)
Это похоже на ошибку для меня, но я открыт, чтобы видеть, сделал ли я что-то здесь неправильно.Или, может быть, это просто не поддерживается.Я использую Kotlin 1.3.11.Такое же поведение на JVM и Android.
Код, который ищет аннотацию:
Log.d("@@@@@", "\n\nDump of $kclass")
val ctor = kclass.constructors.first()
Log.d("@@@@@", "Constructor parameters")
ctor.parameters.forEach { p ->
Log.d("@@@@@", p.toString())
Log.d("@@@@@", p.annotations.size.toString())
p.annotations.forEach { a ->
Log.d("@@@@@", " " + a.annotationClass)
}
}
Log.d("@@@@@", "kotlin functions")
kclass.functions.forEach { f ->
Log.d("@@@@@", f.toString())
if (f.annotations.isNotEmpty()) {
Log.d("@@@@@", "*** " + f.annotations.toString())
}
}
Log.d("@@@@@", "kotlin members")
kclass.members.forEach { f ->
Log.d("@@@@@", f.toString())
if (f.annotations.isNotEmpty()) {
Log.d("@@@@@", "*** " + f.annotations.toString())
}
}
Log.d("@@@@@", "kotlin declared functions")
kclass.declaredFunctions.forEach { f ->
Log.d("@@@@@", f.toString())
if (f.annotations.isNotEmpty()) {
Log.d("@@@@@", "*** " + f.annotations.toString())
}
}
val t = kclass.java
Log.d("@@@@@", "java constructors")
t.constructors.forEach { f ->
Log.d("@@@@@", f.toString())
}
Log.d("@@@@@", "java methods")
t.methods.forEach { f ->
Log.d("@@@@@", f.toString())
if (f.annotations.isNotEmpty()) {
Log.d("@@@@@", "*** " + f.annotations.toString())
}
}
Log.d("@@@@@", "java fields")
t.fields.forEach { f ->
Log.d("@@@@@", f.toString())
if (f.annotations.isNotEmpty()) {
Log.d("@@@@@", "*** " + f.annotations.toString())
}
}