Почему Kotlin не позволяет использовать lateinit с примитивными типами?

в языке Котлин мы, по умолчанию, должны инициализировать каждую переменную, когда она вводится. Чтобы избежать этого,lateinit ключевое слово может использоваться. Ссылаясь на lateinit переменная до ее инициализации приводит к исключению среды выполнения.

lateinit не может, однако, использоваться с примитивными типами. Почему это так?

2 ответов


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

для примитивных типов нет такого значения, поэтому нет способа отметить свойство как неинициализированное и предоставить диагностику, которая lateinit нужно предоставить. (Мы могли бы попытаться использовать отдельный маркер, но этот маркер не будет обновляться при инициализации поля через отражение, которое является основным случаем использования lateinit).

таким образом, lateinit поддерживается только для свойств типов объектов.


короткий ответ заключается в том, что с примитивами, вы всегда можете использовать 0 по умолчанию, и с типами nullable null по умолчанию. Только не-nullable не-примитивные типы могут нуждаться lateinit работать вокруг типа системы безопасности.

на самом деле нет необходимости инициализировать переменную в Kotlin, пока она имеет значение до первый доступ, и это может быть статически доказана. Что означает, что этот код идеально действительно:

fun main(args: Array<String>) {
    var x: Int
    val y: Double

    x = 0
    y = x + 0.1

    println("$x, $y") 
}

но есть (редкие) случаи, когда инициализация не может быть статически доказана. Наиболее распространенным случаем является поле класса, которое использует любую форму инъекции зависимостей:

class Window {
    @Inject lateinit parent: Parent
}