Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin: workaround for no lateinit when using custom setter?

Tags:

android

kotlin

In my activity I have a field that should be non-nullable and has a custom setter. I want to initialize the field in my onCreate method so I added lateinit to my variable declaration. But, apparently you cannot do that (at the moment): https://discuss.kotlinlang.org/t/lateinit-modifier-is-not-allowed-on-custom-setter/1999.

These are the workarounds I can see:

  • Do it the Java way. Make the field nullable and initialize it with null. I don't want to do that.
  • Initialize the field with a "default instance" of the type. That's what I currently do. But that would be too expensive for some types.

Can someone recommend a better way (that does not involve removing the custom setter)?

like image 887
Tobias Uhmann Avatar asked Sep 22 '17 14:09

Tobias Uhmann


People also ask

What if Lateinit is not initialized?

If we don't initialize a lateinit variable before using it gives an error of “lateinit property has not been initialized”. You can check if the lateinit variable has been initialized or not before using it with the help of isInitialized() method.

Should you use Lateinit Kotlin?

Use lateinit for properties that cannot be initialized in a constructor. Don't you mean usse lateinit for properties that can be initialized in the constructor. If you use lateinit and don't initialize it a constructor then you run the risk of accessing it before its been initialized resulting in a exception.

How do you Uninitialize Lateinit variable in Kotlin?

lateinit var is only for first time initialization, for cases when you know that your variable is not nullable but you cannot initialize it in constructor(for example in android framework). There is no point in having lateinit var if you "uninitialize" it after. Kotlin does not allow this kind of manipulation.

Why Lateinit property has not been initialized?

This is because whenever a lateinit property is accessed, Kotlin provides it a null value under the hood to indicate that the property has not been initialized yet.


1 Answers

Replace it with a property backed by nullable property:

private var _tmp: String? = null
var tmp: String
    get() = _tmp!!
    set(value) {_tmp=value; println("tmp set to $value")}

Or this way, if you want it to be consistent with lateinit semantics:

private var _tmp: String? = null
var tmp: String
    get() = _tmp ?: throw UninitializedPropertyAccessException("\"tmp\" was queried before being initialized")
    set(value) {_tmp=value; println("tmp set to $value")}
like image 142
Pavlus Avatar answered Oct 07 '22 00:10

Pavlus