Свойство должно быть инициализированным или абстрактным

121

Должно быть, это глупый вопрос, но я новичок в Kotlin и не нашел решения.

Как объявить поле класса? Как и в java:

protected SharedPreferences mSharedPreferences;

А позже в onCreate():

mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)

Теперь я могу использовать его где угодно (в подклассах этого базового действия).

Я пытаюсь сделать то же самое в Котлине:

protected var sharedPreferences : SharedPreferences

И в onCreate():

sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)

Но получаю предупреждение: «Свойство должно быть инициализировано или быть абстрактным».

Антон Шкуренко
источник

Ответы:

188

Если вы хотите инициализировать свойство вне конструктора, то, возможно, вы ищете свойства с поздней инициализацией . Объявите свойство с lateinitмодификатором, который позволит пропустить требуемый в противном случае инициализатор и приведет к сбою доступа к свойству с исключением, пока ему не будет присвоено какое-либо значимое значение:

protected lateinit var sharedPreferences: SharedPreferences
Александр Удалов
источник
12
Я пробовал использовать "protected var sharedPreferences: SharedPreferences? = Null", и он тоже работает, в чем разница?
Антон Шкуренко
Я вижу, что если я использую Dagger2 для DI, мне придется использовать ваш вариант, верно?
Антон Шкуренко
30
Разница в том, что вы можете объявить значения, не допускающие значения NULL, с помощью lateinit.
Кирилл Рахман
16

Вытягивая это из комментариев из ответа Александра Удалова для наглядности. Для свойств, допускающих значение NULL:

protected var sharedPreferences : SharedPreferences? = null

... и присвоить ему значение позже.

Том Ховард
источник