Home > Mobile >  Strange behaviour of boxed nullable integers
Strange behaviour of boxed nullable integers

Time:10-04

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;
  • Related