«та же подпись JVM», реализующая интерфейс kotlin, содержащий метод получения

#intellij-idea #kotlin #interface

#intellij-idea #kotlin #интерфейс

Вопрос:

 interface MyInterface {
    fun getTheString(): String
}
  
 class MyClass(var theString: String) : MyInterface {
    ...
}
  

обычно, когда у меня есть переменная в конструкторе для класса, он создает средство получения и установки для этой переменной. В MyClass методы getTheString() и setTheString(String) существуют, когда они не реализованы MyInterface .

При MyClass реализации MyInterface я получаю сообщение об ошибке:

Случайное переопределение: следующие объявления имеют ту же сигнатуру JVM (getTheString()Ljava /lang/String;):

  • public final fun (): строка, определенная в MyClass
  • общедоступная абстрактная функция getTheString(): строка, определенная в MyClass

У меня также есть ошибка: класс ‘MyClass’ не является абстрактным и не реализует абстрактный член public abstract fun getTheString(): строка, определенная в MyInterface.

Итак, у меня есть несколько вопросов:

  1. Почему при реализации интерфейса генерируются 2 метода получения с одной и той же сигнатурой JVM, а один метод получения генерируется без реализации интерфейса?
  2. Почему он жалуется, что я не реализовал getTheString() метод, когда этот метод автоматически генерируется kotlin?
  3. Как я могу заставить геттер, сгенерированный переменной, стать реализацией метода в интерфейсе?

Комментарии:

1. Вы пробовали @get:JvmName("getTheString_") ?

2. @EpicPandaForce, который устраняет ошибку на var theString , но не использует метод, сгенерированный переменной, в качестве реализации метода в интерфейсе

3. Если вам просто нужна пользовательская реализация свойства, определенного в конструкторе, проверьте мой ответ.

Ответ №1:

Если интерфейс действительно на Kotlin, и вы можете его изменить, он должен быть

 interface MyInterface {
    val theString: String
}
  

во-первых. Java все равно будет видеть getTheString() , но ее приятнее как внедрять, так и использовать в Kotlin.

В противном случае хорошим вариантом является

 class MyClass(@set:JvmName("setTheString") var _theString: String) : MyInterface {
    override fun getTheString() = _theString
}
  

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

 class MyClass(private var _theString: String) : MyInterface {
    override fun getTheString() = _theString
    fun setTheString(value: String) { 
        _theString = value
    }
}
  

Обратите внимание, что если интерфейс выполнен на Java, getTheString() он будет виден Kotlin как свойство.

Смотрите проблемы https://youtrack.jetbrains.com/issue/KT-6653 и https://youtrack.jetbrains.com/issue/KT-19444 в системе отслеживания ошибок Kotlin.

Комментарии:

1. Лучшими вариантами являются первые два, которые, похоже, ни к чему не связаны в вашем ответе. Я могу удалить третий, но, пожалуйста, отредактируйте свой ответ самостоятельно.