Я хотел бы оставить этот ответ на случай, если кто-то новый в Котлине, как я, столкнется с этим.
Я изучал codelab об Android и @get:Query
упоминал в проекте, который привел меня к этому вопросу, затем после хорошего исследования я обнаружил, что эта концепция относится к Kotlin, а не к Android, и называется аннотация" Цели использования сайта ".
Аннотации Цели использования сайта
Проще говоря, аннотация цели использования сайта позволяет любому @Annotations
в вашем исходном коде оказаться в очень конкретном месте в вашем скомпилированном байт-коде или в коде Java, сгенерированном kapt.
Kotlin поддерживает следующие значения целевых объектов использования, которые соответствуют:
- делегат - поле, хранящее делегированное свойство
- field - поле, созданное для свойства
- file - класс, содержащий функции верхнего уровня и свойства, определенные в этом файле
- get / set - свойство getter / setter
- param - параметр конструктора
- property - свойство Котлина, оно недоступно из Java-кода
- приемник - параметр приемника функции или свойства расширения
Воспользуемся простым классом:
class Example(@param:ColorRes val resId:Int )
Мы использовали use-site param
с @ColorRes
, который применит @ColorRes
к параметру конструктора в сгенерированном классе Java:
public final class Example {
private final int resId;
public final int getResId() {
return this.resId;
}
public Example(@ColorRes int resId) {
this.resId = resId;
}
}
Давайте изменим use-site на field
:
class Example(@field:ColorRes val resId:Int )
Теперь аннотация @ColorRes
будет применена к полю resId
сгенерированного класса:
public final class Example {
@ColorRes
private final int resId;
public final int getResId() {
return this.resId;
}
public ViewModel(int resId) {
this.resId = resId;
}
}
Используя сайт использования get
:
class Example(@get:ColorRes val resId:Int )
Метод получения поля resId
будет иметь аннотацию @ColorRes
:
public final class Example {
private final int resId;
@ColorRes
public final int getResId() {
return this.resId;
}
public Example(int resId) {
this.resId = resId;
}
}
So!
В нашем коде для Android:
@Dao
interface MovieDao {
@get:Query("select poster_path from Movie")
val popularMovieImageList: LiveData<List<String>>
}
Сайт использования аннотаций get
потребует, чтобы реализация MovieDao
применила Query("...")
к методу получения popularMovieImageList
:
public final class MovieDaoImpl {
private final LiveData<List<String>> popularMovieImageList;
@Query("select poster_path from Movie")
public final LiveData<List<String>> getPopularMovieImageList() {
...
}
}
ПРИМЕЧАНИЕ. Предыдущий код Java взят из моего воображения, я понятия не имею, как будет выглядеть сгенерированная реализация для этого Dao от Room
, просто чтобы поддержать мое объяснение.
Пока!
Почему @get:Query
вместо @Query
?
Итак, из документации Android мы используем @Query
для методов:
Помечает метод в Dao
аннотированном классе как метод запроса.
И из документации Kotlin мы не используйте Annotation Use-site targets
для методов, но для a property or a primary constructor parameter
:
Когда вы аннотируете свойство или параметр первичного конструктора, существует несколько элементов Java, которые генерируются из соответствующего элемента Kotlin, и, следовательно, несколько возможных мест для аннотации в сгенерированном байт-коде Java.
Насколько я узнал из Kotlin, средство получения свойств не может иметь параметра, а вместо этого использует для этого методы.
Я думаю, что теперь все остальные недоразумения должны быть прояснены.
Использованная литература:
person
Ahmed Shendy
schedule
09.10.2020
fun
. Что заставляет вас думать, что это не вариант? - person ianhanniballake   schedule 24.06.2020Constant.category
? Это на самом делеconst
? - person ianhanniballake   schedule 24.06.2020