Случайное переопределение: следующие объявления имеют одну и ту же подпись JVM

Я получаю эту ошибку в Kotlin в этой части:

class GitHubRepoAdapter(private val context: Context,
    private val values: List<GithubRepo>) : ArrayAdapter<GithubRepo>(context, R.layout.list_item,
    values) {

частный контекст val: контекст

в журнале говорится:

Ошибка: (14, 25) Случайное переопределение: следующие объявления имеют одна и та же подпись JVM (getContext() Landroid/content/Context;):     fun(): Контекст     fun getContext(): Контекст!

Я не могу понять, что вызывает проблему.

Ответ 1

Это происходит потому, что компилятор Kotlin пытается сгенерировать getter для val context, объявленного в вашем основном конструкторе класса, а именно функцию getContext(), но базовый класс ArrayAdapter<T> уже имеет такую ​​функцию.

Вы можете решить это, выполнив одно из следующих действий:

  • Измените параметр конструктора класса не как val.

     class GitHubRepoAdapter(context: Context, ...
    

    В этом случае геттер не будет сгенерирован, и конфликт исчезнет.

    Это, по-видимому, предпочтительное решение в вашем случае, потому что даже без переоценки уже существует синтетическое свойство context, полученное от Java getter.

  • Используйте @JvmName аннотация, применить ее к context свойство getter:

     class GitHubRepoAdapter(@get:JvmName("getContext_") private val context: Context, ...
    

    Это заставит компилятор сгенерировать геттер с другим именем JVM (тем, который указан в аннотации), что позволит избежать конфликта, но сделать его доступным с Java менее интуитивным (тем более, что будут две аналогичные функции). В Котлине вы все равно сможете использовать свойство с его первоначальным именем context.

Ответ 2

В дополнение к уже предоставленному ответу...

  • Или вы можете сохранить val (или var), но изменить имя параметра на то, что не сталкивается с объявлением суперкласса.

В объявлении класса параметры в объявлениях конструктора часто больше, чем просто параметры. Используя val или var, вы фактически объявляете элементы свойств (а не только параметры). И вместе с членами собственности появляются автоматические "геттеры" (и "сеттеры" в случае var). Автоматический приемник в случае OP называется getContext() , но базовый класс уже имеет getContext() (та же подпись).

Скорее всего, целью здесь было просто передать context супер, и в этом случае другой ответ лучше всего работает. Но в случае, когда требуется новое свойство, но выбранное имя сталкивается с другим назначенным членом супер, изменение имени является альтернативой.

Короче, изменение имени применяется, когда делать требуется новая переменная участника , но суперкласс уже предоставляет другому члену то же имя.