Константы времени компиляции в Kotlin

Если значение свойства только для чтения известно во время компиляции, отметьте его как постоянную времени компиляции с помощью модификатора const. Такие свойства должны соответствовать следующим требованиям:

  • Верхний уровень или член объявления объекта или сопутствующий объект (companion object).
  • Инициализируется значением типа String или примитивным типом
  • Нет специального получателя

Такие свойства можно использовать в аннотациях:

const val SUBSYSTEM_DEPRECATED: String = "This subsystem is deprecated"
 
@Deprecated(SUBSYSTEM_DEPRECATED) fun foo() { ... }

Свойства и переменные с поздней инициализацией

Обычно свойства, объявленные как имеющие ненулевой тип, должны быть инициализированы в конструкторе. Однако довольно часто это не удобно. Например, свойства могут быть инициализированы с помощью внедрения зависимостей или с помощью метода настройки модульного теста. В этом случае вы не можете указать в конструкторе инициализатор, отличный от null, но вы все равно хотите избежать проверки null при ссылке на свойство внутри тела класса.

Чтобы справиться с этим случаем, вы можете пометить свойство модификатором lateinit:

public class MyTest {
    lateinit var subject: TestSubject
 
    @SetUp fun setup() {
        subject = TestSubject()
    }
 
    @Test fun test() {
        subject.method()  // разыменование напрямую
    }
}

Модификатор можно использовать для свойств var, объявленных внутри тела класса (не в основном конструкторе, и только тогда, когда свойство не имеет настраиваемого средства получения или установки) и, начиная с Kotlin 1.2, для свойств верхнего уровня и локальных переменных. Тип свойства или переменной не должен быть нулевым и не должен быть примитивным типом.

Доступ к свойству lateinit до его инициализации вызывает специальное исключение, которое четко определяет свойство, к которому осуществляется доступ, и тот факт, что оно не было инициализировано.

Проверка инициализации переменной lateinit (начиная с версии 1.2)

Чтобы проверить, инициализирована ли уже переменная lateinit, используйте .isInitialized для ссылки на это свойство:

if (foo::bar.isInitialized) {
    println(foo.bar)
}

Эта проверка доступна только для свойств, которые лексически доступны, т. н. объявлены в том же типе, или в одном из внешних типов, или на верхнем уровне в том же файле.

Делегированные свойства

Наиболее распространенный вид свойств просто считывает (и, возможно, записывает) резервное поле. С другой стороны, с помощью настраиваемых геттеров и сеттеров можно реализовать любое поведение свойства. Где-то посередине есть определенные общие закономерности того, как собственность может работать. Несколько примеров: отложенные значения, чтение с карты по заданному ключу, доступ к базе данных, уведомление слушателя о доступе и т. д.

Такое обычное поведение можно реализовать в виде библиотек с использованием делегированных свойств.


Читайте также:


Комментарии

Популярные сообщения из этого блога

Строки в Kotlin

Наследование в Kotlin

Возврат и прыжки в Kotlin