Kotlin - Как решить между "lateinit" и "nullable variable"?

Я запутался в переменной lateinit и nullable, которую можно использовать для переменной.

lateinit var c: String
var d: String? = null
c = "UserDefinedTarget"

// if not added initialisation for c than throws UninitializedPropertyAccessException
if (c == "UserDefinedTarget") {
    //do some stuff.
}
//not throws any exception whether d is initialise or not.
if(d == "UserDefinedTarget") {
     //do some stuff
}

Ответ 1

Тип, который является нулевым, - это просто то, что имеет допустимое состояние, которое равно null.

Недействительный поздний init var представляет что-то, где null является недопустимым состоянием, но по какой-то причине его невозможно заполнить в конструкторе.

Активность Android - хороший пример использования lateinit. Действия должны иметь конструктор без аргументов, и их жизненный цикл действительно начинается с onCreate().

Ответ 2

Это две концепции полностью разные.

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

Однако вы должны иметь в виду, что доступ к свойству lateinit до того, как он был инициализирован, выдает исключение. Это означает, что вы должны использовать их, только если вы абсолютно уверены, что они будут инициализированы.

Сбрасываемые типы, с другой стороны, используются, когда переменная может содержать null.


class A {
    lateinit var a: String

    fun cat() {
        print(a.length)  // UninitializedPropertyAccessException is thrown
        a = "cat"
        print(a.length)  // >>> 3
    }
}

class B {
    var b: String? = null

    fun dog() {
        print(b.length)  // won't compile, null check is obligatory here
        print(b?.length) // >>> null
        b = "dog"
        print(b?.length) // >>> 3
    }
}

Для получения дополнительной информации:

Ответ 3

Это зависит. Необязательная переменная означает, что переменная может содержать значение или значение null. lateinit означает, что переменная должна инициализироваться позже. Он должен быть инициализирован перед его доступом. Если вы попытаетесь получить доступ к неинициализированной переменной lateinit UninitializedPropertyAccessException, она будет выбрана.

Всегда лучше избегать использования нулей в вашем приложении. Нули - зло. Поэтому, если вы можете инициализировать переменную в onCreate, тогда лучше использовать lateinit. Кроме того, если вы используете инъекцию зависимостей в своем приложении, а поля должны быть введены, это также допустимый случай использования lateinit вместо обработки нулей.

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