盒装可为空整数的奇怪行为
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
请注意,因为 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 中的可空变量有疑问 我在 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
请注意,因为 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;