盒装可为空整数的奇怪行为

Strange behaviour of boxed nullable integers

我对 Kotlin 中的可空变量有疑问 我在 Kotlin 文档中找到了这个例子:

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

产出

true
false

他们解释说这是JVM对-128到127之间的Integer的内存优化。它不适用于b引用,所以它们是不同的对象。

然后我将 a 和 b 转换为可为 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

产出

true
true

是什么造成了这种差异?谁能给我解释一下吗?

在第一种情况下(不可为空),装箱发生在所有这些行上,正如您正确识别的那样:

val boxedA: Int? = a
val anotherBoxedA: Int? = a

val boxedB: Int? = b
val anotherBoxedB: Int? = b

这是因为Int?在Java中一般会翻译成java.lang.Integer

所以在最后两行创建了 2 个新的、不同的 java.lang.Integer 实例,因为 b 大于 127。

但是,在第二种情况下,可以为 nullable,装箱只发生在这些行上:

val a: Int? = 100

val b: Int? = 10000

请注意,因为 ab 可以为空,所以它们现在是包装类型 java.lang.Integer。它们已经装箱!因此,当您将它们分配给 boxedAboxedBanotherBoxedAanotherBoxedB 时,不会发生装箱,也不会创建 java.lang.Integer 的新实例。您只是将 Integer 类型的变量分配给另一个 Integer.

类型的变量

因此,java.lang.Integer只有一个实例存储10000,它是在val b: Int? = 10000.

行创建的

如果您将 Kotlin 翻译成 Java:

可能会有所帮助
Integer b = 10000; // boxing only occurs here
Integer boxedB = b;
Integer anotherBoxedB = b;