Выбор ответа Senior Null-safety обновлено
NPE при вызове открытого метода из конструктора
Вопрос
Почему этот код упадёт с NullPointerException, хотя name объявлен как String?
open class Base {
init { describe() }
open fun describe() {}
}
class Child(val name: String) : Base() {
override fun describe() { println(name.length) }
}
fun main() { Child("Kotlin") }
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Правильный ответ: init базы вызывает describe() до инициализации name. Порядок инициализации: сначала отрабатывает конструктор и init базового класса, потом поля наследника.
Варианты ответа
printlnне умеет печататьIntбезtoString()initбазы вызываетdescribe()до инициализацииnameправильный ответ- Kotlin не проверяет non-null типы в рантайме совсем
override funнельзя вызывать изinitбазового класса
Разбор
Порядок инициализации: сначала отрабатывает конструктор и init базового класса, потом поля наследника. Открытый метод, вызванный из init базы, уходит в реализацию наследника, где name ещё не присвоен, а на JVM это null. name.length бросит NPE. Компилятор предупреждает о вызове открытого члена из конструктора. Kotlin проверяет null в рантайме на границах (например, параметры публичных функций), но не здесь.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.