I have a problem with nullable variable in Kotlin I found this example in the Kotlin docs:
val a: Int = 100
val boxedA: Int? = a
val anotherBoxedA: Int? = a
val b: Int = 10000
val boxedB: Int? = b
val anotherBoxedB: Int? = b
println(boxedA === anotherBoxedA) // true
println(boxedB === anotherBoxedB) // false
output
true
false
They explain that this is the memory optimization that JVM applies to Integer s between -128 and 127. It doesn't apply to the b references, so they are different objects.
then I convert a and b to nullable
val a: Int? = 100
val boxedA: Int? = a
val anotherBoxedA: Int? = a
val b: Int? = 10000
val boxedB: Int? = b
val anotherBoxedB: Int? = b
println(boxedA === anotherBoxedA) // true
println(boxedB === anotherBoxedB) // true
output
true
true
What makes this difference? Can anyone please explain to me?
CodePudding user response:
In the first case (non-nullable), boxing occurs on all of these lines, as you have correctly identified:
val boxedA: Int? = a
val anotherBoxedA: Int? = a
val boxedB: Int? = b
val anotherBoxedB: Int? = b
This is because Int?
generally translates to java.lang.Integer
in Java.
So 2 new, different, instances of java.lang.Integer
are created on the last two lines, because b
is greater than 127.
However, in the second case with nullables, boxing only occurs on these lines:
val a: Int? = 100
val b: Int? = 10000
Note that because a
and b
are nullable, they are now of wrapper type java.lang.Integer
. They are already boxed! So when you assign them to boxedA
, boxedB
, anotherBoxedA
and anotherBoxedB
, no boxing occurs, and no new instances of java.lang.Integer
are created. You are just assigning a variable of type Integer
to another variable of type Integer
.
Therefore, there is only one instance of java.lang.Integer
storing 10000, and that is created at the line val b: Int? = 10000
.
It might help if you translate your Kotlin to Java:
Integer b = 10000; // boxing only occurs here
Integer boxedB = b;
Integer anotherBoxedB = b;