884

I wonder if there is a way to check if a lateinit variable has been initialized. For example:

class Foo() { private lateinit var myFile: File fun bar(path: String?) { path?.let { myFile = File(it) } } fun bar2() { myFile.whateverMethod() // May crash since I don't know whether myFile has been initialized } } 
4
  • 4
    Maybe what you need is to make the property nullable (change type to File?) and just check if it is null instead? Commented Jun 3, 2016 at 16:40
  • 1
    Well, I actually tried that and it will do the trick, however I will have to edit the allSeries var to seriesDir?.listFiles()?.map { it.name }?.toTypedArray(), which is not very "pretty" Commented Jun 3, 2016 at 20:24
  • 2
    You can do a plain old null check and smart cast will make it prettier. if (seriesDir != null) { allSeries = seriesDir.listFiles().map { it.name }.toTypedArray() } Commented Jun 3, 2016 at 20:28
  • Please consider accepting more up to date answer Commented Mar 18, 2019 at 7:22

8 Answers 8

1723

There is a lateinit improvement in Kotlin 1.2 that allows you to check the initialization state of lateinit variable directly:

lateinit var file: File if (this::file.isInitialized) { ... } 

See the annoucement on JetBrains blog or the KEEP proposal.

UPDATE: Kotlin 1.2 has been released. You can find lateinit enhancements here:

Sign up to request clarification or add additional context in comments.

17 Comments

@fer.marino: Well, Kotlin 1.2 actually allows you to use lateinit also for local variables, see kotlinlang.org/docs/reference/…
this::lateinitVar.isInitialized
what is meaning of :: before file?
@MalwinderSingh it creates a member reference or a class reference.
How do we check this for local lateinit, where this is something different?
|
195

Using .isInitialized property one can check initialization state of a lateinit variable.

if (::file.isInitialized) { // File is initialized } else { // File is not initialized } 

4 Comments

This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. - From Review
@gforce301 It will definetly used for checking.
Well this is the only answer that worked for me on Android Studio having Kotlin version 1.3
@gforce301 why does this not answer the question?? Was the original question changed? It seems to answer it now...
112

You can easily do this by:

::variableName.isInitialized 

or

this::variableName.isInitialized 

But if you are inside a listener or inner class, do this:

this@OuterClassName::variableName.isInitialized 

Note: The above statements work fine if you are writing them in the same file(same class or inner class) where the variable is declared but this will not work if you want to check the variable of other class (which could be a superclass or any other class which is instantiated), for ex:

class Test { lateinit var str:String } 

And to check if str is initialized:

enter image description here

What we are doing here: checking isInitialized for field str of Test class in Test2 class. And we get an error backing field of var is not accessible at this point. Check a question already raised about this.

Comments

49

Try to use it and you will receive a UninitializedPropertyAccessException if it is not initialized.

lateinit is specifically for cases where fields are initialized after construction, but before actual use (a model which most injection frameworks use). If this is not your use case lateinit might not be the right choice.

EDIT: Based on what you want to do something like this would work better:

val chosenFile = SimpleObjectProperty<File?> val button: Button // Disables the button if chosenFile.get() is null button.disableProperty.bind(chosenFile.isNull()) 

6 Comments

I have a JavaFX application, and I have a button which will be always disables unless a variable (which is lateinit) has been initialized. In other words: I want the button to be disabled as long as the variable hasn't been initialized. Is there a good way to do that?
@MathewHany How would it be getting initialized normally? You might want to look at property getter/setters and a SimpleBooleanProperty which you can bind to the disabled property of the button
To be more specific, I have a simple app that contains 4 buttons, the first button will open a DirectoryChooser dialog, and the other 3 will be disabled, when the user choose a directory then all the other buttons will be available to the user.
@MathewHany you can natively implement that using a SimpleObjectProperty to hold the chosen file, then using the isNull binding to disable the other buttons.
kotlinlang.org/docs/reference/… xsveda answer is more up to date
|
34

If you have a lateinit property in one class and need to check if it is initialized from another class

if(foo::file.isInitialized) // this wouldn't work 

The workaround I have found is to create a function to check if the property is initialized and then you can call that function from any other class.

Example:

class Foo() { private lateinit var myFile: File fun isFileInitialised() = ::file.isInitialized } // in another class class Bar() { val foo = Foo() if(foo.isFileInitialised()) // this should work } 

1 Comment

Kind of ridiculous that you need to add a function just to check if something is initialized.
21

Accepted answer gives me a compiler error in Kotlin 1.3+, I had to explicitly mention the this keyword before ::. Below is the working code.

lateinit var file: File if (this::file.isInitialized) { // file is not null } 

1 Comment

I am using a local init variable when I use this check that gives an error like unresolved reference
21

Checking lateinit var

To check whether a lateinit var was initialized or not, simply use an .isInitialized boolean on the property reference :: .

if (foo::bar.isInitialized) { println(foo.bar) } 

Kotlin Playground's code may look like this:

fun main() { var declarative = Declarative() declarative.checkLateInit() } class Declarative { lateinit var compose: String fun checkLateInit() { println(this::compose.isInitialized) compose = "Jetpack Compose 1.4" if (this::compose.isInitialized) { println(this.compose) } } } // Result: // false // Jetpack Compose 1.4 

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

2 Comments

what is meaning of :: before bar?
@Malwinder Singh "creates a member reference or a class reference" - Kotlin Doc
3
kotlin.UninitializedPropertyAccessException: lateinit property clientKeypair has not been initialized 

Bytecode says...blah blah..

public final static synthetic access$getClientKeypair$p(Lcom/takharsh/ecdh/MainActivity;)Ljava/security/KeyPair; `L0 LINENUMBER 11 L0 ALOAD 0 GETFIELD com/takharsh/ecdh/MainActivity.clientKeypair : Ljava/security/KeyPair; DUP IFNONNULL L1 LDC "clientKeypair" INVOKESTATIC kotlin/jvm/internal/Intrinsics.throwUninitializedPropertyAccessException (Ljava/lang/String;)V L1 ARETURN 

L2 LOCALVARIABLE $this Lcom/takharsh/ecdh/MainActivity; L0 L2 0 MAXSTACK = 2 MAXLOCALS = 1

Kotlin creates an extra local variable of same instance and check if it null or not, if null then throws 'throwUninitializedPropertyAccessException' else return the local object. Above bytecode explained here Solution Since kotlin 1.2 it allows you to check weather lateinit var has been initialized or not using .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.