88

I'm trying to check if a lateinit property has been initialized.
In Kotlin 1.2 we now have the isInitialized method for that. It works when I do that in the class where the lateinit property is declared. But when I try to call this from another class I get the following warning:

Backing field of 'lateinit var foo: Bar' is not accessible at this point

My model class (let's say Person) is written in Java
Two other classes (let's say Test1 and Test2) are written in Kotlin

Example:

class Test1 { lateinit var person: Person fun method() { if (::person.isInitialized) { // This works } } } 

-

class Test2 { lateinit var test1: Test1 fun method() { if (test1::person.isInitialized) { // Error } } } 

Any chance to get this working?

My current workaround is to make a method in Test1 which returns isInitialized from the person property.

fun isPersonInitialized(): Boolean = ::person.isInitialized //in Test2: if (test1.isPersonInitialized()) { // Works } 
6
  • I don't know the answer. But why you use isInitialized over nullable? lateinit show always be initialized before the object being use. Commented Nov 29, 2017 at 10:06
  • @Eledgy your code does not compile. you cannot put an if-expression directly in a class body. i think you forgot to wrap it inside an init block. i know, this does not fix your inital problem. Commented Nov 29, 2017 at 10:11
  • @Joshua I have one case where person may not be initialized yet Commented Nov 29, 2017 at 10:19
  • @WilliMentzel It's just an example, I've put the code in a method Commented Nov 29, 2017 at 10:21
  • 2
    @ElegyD Then, you should use Person?. If you abuse lateinit, you need an if everytime you access person which make you go back to Java with null checking. Commented Nov 29, 2017 at 10:25

3 Answers 3

112

A really simple workaround to the constraints described by the accepted answer is the following:

class LateClass { lateinit var thing: Thing fun isThingInitialized() = ::thing.isInitialized } class Client { val lateClass = LateClass() ... things happen ... if (lateClass.isThingInitialized() { // do stuff with lateClass.thing, safely } } 
Sign up to request clarification or add additional context in comments.

8 Comments

Very nice and elegant. converted to property.. val isThingInitialized: Boolean = ::thing.isInitialized
@TejasviHegde won't isThingInitialized be set to false on creation and never be updated to true once thing is initialized given that it is immutable?
@ThomasSunderland isThingInitialized is not immutable, it's a function.
val isThingInitialized: Boolean = ::thing.isInitialized will always be false since is pre-calculated only once. You can make a function as in this solution, or make a lazy field: val isThingInitialized: Boolean by lazy { ::thing.isInitialized }
@TejasviHegde using a property can only be successful if you set up a getter to it.
|
37

According to the docs:

This check is only available for the properties that are lexically accessible, i.e. declared in the same type or in one of the outer types, or at top level in the same file.

Which is why you cannot check that in the main function.

1 Comment

this should still be considered at kotlin v1.3.+ :)
22

My version as a Kotlin property.

class LateClass { lateinit var thing: Thing val isThingInitialized get() = this::thing.isInitialized } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.