Константы времени компиляции в 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)
}
Эта проверка доступна только для свойств, которые лексически доступны, т. н. объявлены в том же типе, или в одном из внешних типов, или на верхнем уровне в том же файле.
Делегированные свойства
Наиболее распространенный вид свойств просто считывает (и, возможно, записывает) резервное поле. С другой стороны, с помощью настраиваемых геттеров и сеттеров можно реализовать любое поведение свойства. Где-то посередине есть определенные общие закономерности того, как собственность может работать. Несколько примеров: отложенные значения, чтение с карты по заданному ключу, доступ к базе данных, уведомление слушателя о доступе и т. д.
Такое обычное поведение можно реализовать в виде библиотек с использованием делегированных свойств.
Читайте также:
Комментарии
Отправить комментарий