Переменные создают свои собственные методы получения, но вы также явно определяете их.Когда вы объявляете var или val, они обычно имеют свои собственные геттеры, автоматически генерируемые 1 .Частные значения или переменные не нужны, если вы не создаете пользовательский метод получения.
Но во всех остальных случаях это:
val x: Int = TODO()
генерирует геттер 1 .
В вашем случае я бы рекомендовал использовать val непосредственно в интерфейсе.Видите ли, сгенерированный метод get имеет то же имя, что и метод getHash, который вы явно объявили.Получатели также не переопределяют методы (если только вы не аннотируете это одной из аннотаций @Jvm, и я не помню, какие из них, но вы все равно не нужны).
Таким образом, вы изменяете свой интерфейс на:
interface IData {
val hash: Int
val uuid: UUID
}
И удаляете геттеры в переопределенном объекте и добавляете override
к значениям:
dataList.add(object : IData {
override val hash: Int by lazy { dataFetchers.size+System.currentTimeMillis().toInt() }
override val uuid: UUID by lazy { UUID.randomUUID() }
}
Первый интерфейс фактически эквивалентен объявлению интерфейса с методами get и set.Если вы переопределите его из Java, он попросит вас переопределить getHash()
и getUid()
, и вам нужно будет объявить поле локально.Kotlin работает по-другому, потому что он автоматически генерирует сеттеры.
И так как вы можете объявлять переменные в интерфейсах, не мешая взаимодействию Java, я настоятельно рекомендую вам использовать это над аннотациями @ Jvm * (главным образом потому, что это облегчает пониманиекод, хотя это личное предпочтение).
Кроме того, если вы декомпилируете байт-код Kotlin, вы увидите, для чего компилируется интерфейс с переменными:
public interface IData {
int getHash();
@NotNull
UUID getUuid();
}
Таким образом, он идентичен тому, который был у вас изначально,просто без конфликтов в дочерних классах из-за конфликтов имен переменных.
И причина того, что только у одного есть конфликт, заключается в том, что, как вы видите в интерфейсе, val uuid
создает геттер с именем getUuid
, а ваш интерфейс объявляет getUUID
.Методы в Java и Kotlin чувствительны к регистру, поэтому они не конфликтуют.Если вы переименуете свою переменную в верхний регистр UUID
, вы также столкнетесь с этим.
1: Предполагается, что переменная / константа отсутствует в методе.Переменные верхнего уровня, переменные в интерфейсах, перечисления, классы, объекты и сопутствующие объекты - все генерируют геттеры / сеттеры, но если вы объявите переменную внутри метода, у нее, естественно, не будет геттеров и сеттеров, где это применимо.