Kotlin 盒装​​ Int 不一样

Kotlin boxed Int are not the same

请帮助我理解 kotlin 文档中的这段代码:-

val a: Int = 10000
print(a === a) // Prints 'true'
val boxedA: Int? = a
val anotherBoxedA: Int? = a
print(boxedA === anotherBoxedA) // !!!Prints 'false'!!!

现在,我了解到首先 int a = 10000 然后在下一行中使用 ===.

进行比较

现在的问题是,为什么当它分配 boxedA=a 时,它使用 int? 检查它是否为空。是不是可以这样写:-

val boxedA: Int=a

如果我理解错了,请大神指导检查正确的地方或为我解释一下。

it checked if it is null using int?

不是这个意思

Kotlin 的 null 安全功能默认不允许将变量设置为 null。

检查here

val anotherBoxedA: Int? = a

这意味着 anotherBoxedA 可以赋值为 null 或者 可为 null

val anotherBoxedA: Int? = null

这是允许的。

when it assigned boxedA = a, it checked if it is null using int?

我不知道你这是什么意思。使变量具有 Int? 类型使其成为可以存储 Intnull 的变量。此作业没有检查。如果您有一个非空值要分配给变量,只需使其不可为空,类型中没有 ?:

val copyOfA: Int = a

您甚至可以省略类型,并得到 Int 推断:

val copyOfA = a

至于比较:

==在Kotlin中用于按值比较(这相当于在Java中使用equals),===用于比较引用(这== 在 Java).

当您创建 boxedAanotherBoxedA 时,您会在幕后创建两个 Integer 实例(因为可为 null 的变量不能由原语表示)。与 == 比较时它们相等(它们具有相同的值),但与 === 比较时它们不相等(它们是不同的实例)。

你可以查看官方文档的相关部分here

首先,Int 将根据其上下文映射到 java int/Integer。如果 Int 是泛型参数,则其映射类型为 Integer。否则,它是原始类型int。例如:

val a:Int = 1 
//final int a = 1; //mapped to java code

val numbers:List<Int> = asList(1,2,3)
//final List<Integer> numbers  = asList(1, 2, 3); //mapped to java code

其次,将 Int 装箱到 Int? 与 java 将 int 装箱到 Integer 的行为相同,例如:

val a:Int = 1   // int a = 1;
val b:Int? = a; // Integer b = a;

Why the boxed Integers are not the same?

这是因为每个 boxingInteger only caching values in the range [-128, 127]. the the variable a above is out of the cache range, it will create a new Integer 实例而不是使用 cached 值。例如:

//                v--- 1 is in cache range 
val ranged: Int = 1
val boxedRanged1: Int? = ranged
val boxedRanged2: Int? = ranged

println(boxedRanged1 === boxedRanged2) //true

//                   v--- 128 is out of cache range
val excluded: Int = 128
val boxedExcluded1: Int? = excluded
val boxedExcluded2: Int? = excluded

println(boxedExcluded1 === boxedExcluded2) //false