8

Why can't we use lateinit with nullable variables?

lateinit var v: String?

lateinit modifier is not allowed on properties of nullable types

serv-inc
  • 35,772
  • 9
  • 166
  • 188
Abraham Mathew
  • 2,029
  • 3
  • 21
  • 42
  • 1
    I don't know the specifics, but if you think about it, if you'd allow that why would you make it `lateinit`? Just initialise it to `null`. – Fred May 29 '19 at 05:48
  • Look i know i will initialise it with some value but that will be a nullable value, on assigning that value to the variable we declared it will show a warning – Abraham Mathew May 29 '19 at 11:46

6 Answers6

14

lateinit is only for avoid null checks in future, that's why lateinit modifier is not allowed on properties of nullable types.

If you want it to be nullable then simply you can use like var b: String? = null

Gunaseelan
  • 14,415
  • 11
  • 80
  • 128
3

If you want to make a variable of nullable type then you don't need late init . The doc says

Normally, properties declared as having a non-null type must be initialized in the constructor. However, fairly often this is not convenient. For example, properties can be initialized through dependency injection, or in the setup method of a unit test. In this case, you cannot supply a nonnull initializer in the constructor, but you still want to avoid null checks when referencing the property inside the body of a class.

So late init is intended to be used when you intend to initialize a variable somewhere not in the constructor and also want to avoid null checks.

Dishonered
  • 8,449
  • 9
  • 37
  • 50
2

As stated in the documentation, lateinit specializes on non-nullable properties:

Normally, properties declared as having a non-null type must be initialized in the constructor. However, fairly often this is not convenient. For example, properties can be initialized through dependency injection, or in the setup method of a unit test. In this case, you cannot supply a non-null initializer in the constructor, but you still want to avoid null checks when referencing the property inside the body of a class.

Also, if you take a look at the byte code of such a lateinit property, you see that the compiler adds a code block to ensure that this property has been initialized when being accessed. For lateinit properties, null indicates the properties initial but invalid state.

class WithLateInit {
    lateinit var something : String
}

becomes

public final class WithLateInit {
   @NotNull
   public String something;

   @NotNull
   public final String getSomething() {
      String var10000 = this.something;
      if (var10000 == null) { // <- here you can see the lateinit check
         Intrinsics.throwUninitializedPropertyAccessException("something");
      }

      return var10000;
   }

  //setter
}
s1m0nw1
  • 76,759
  • 17
  • 167
  • 196
1

Normally, properties declared as having a non-null type must be initialized in the constructor. However, fairly often this is not convenient.

For example, properties can be initialized through dependency injection, or in the setup method of a unit test. In this case, you cannot supply a non-null initializer in the constructor, but you still want to avoid null checks when referencing the property inside the body of a class.

To handle this case, you can mark the property with the lateinit modifier.

That's why it doesn't support null.

So, if you indicate any var as lateinit meaning compiler simply ignores it for initialization and mark it as non-null type that would be initialized in nearer future and is why it doesn't support nullable type to avoid runtime ambiguities.

Jeel Vankhede
  • 11,592
  • 2
  • 28
  • 58
1

Kotlin's type system is aimed at eliminating the danger of null references from code

so both represent compromises. With lateinit you ensure that the variable will eventually be initialized to non-null. If you cannot even guarantee that, you can use nullable.

serv-inc
  • 35,772
  • 9
  • 166
  • 188
0

One of the main feature in kotlin is Null Safe.

By default it won't allow u to create a null value. You have explicitly defined
var a: String? = null
, If u don't want to initialise any value to the variable there come "lateinit". While using lateinit variable You do pre-check whether it is initialised or not

Abraham Mathew
  • 2,029
  • 3
  • 21
  • 42
Madhu
  • 1,780
  • 23
  • 47