我在 Kotlin 中遇到可为 null 变量的问题 我在 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 转换为可空
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。
但是,在第二种可为空的情况下,装箱仅发生在这些行上:
val a: Int? = 100
val b: Int? = 10000
请注意,由于 a
和 b
可为空,因此它们现在是包装类型 java.lang.Integer
。它们已经装箱了!因此,当您将它们分配给 boxedA
、boxedB
、anotherBoxedA
和 anotherBoxedB
时,不会发生装箱,也不会产生新实例创建了 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;
关于kotlin - 装箱可为空整数的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69415755/