??在看Kotlin的基本類型時(shí),文檔提到,Kotlin中所有東西都是對(duì)象;并且數(shù)字在 Java 平臺(tái)是物理存儲(chǔ)為 JVM 的原生類型,除非我們需要一個(gè)可空的引用(如 Int?)或泛型。 后者情況下會(huì)把數(shù)字裝箱。
?? 剛看到數(shù)字裝箱,猜測(cè)是不是類似Java中基本類型的包裝類,int —> Integer... 然后例子中又提到一個(gè)數(shù)字裝箱不一定保留同一性,判斷的是兩個(gè)數(shù)值的引用地址。如果是按照 Integer來裝箱,boxedA 和 anotherBoxedA 應(yīng)該是兩個(gè)不同的 Integer對(duì)象,引用一定不同。

?? 實(shí)踐出真知,上代碼
fun testPacking() {
val a: Int = 10000
println(a === a) // 輸出“true”
val boxedA: Int? = a
val anotherBoxedA: Int? = a
println(boxedA === anotherBoxedA) // ?。。≥敵觥癴alse”?。?!
}
fun testPacking2() {
val a: Int = 100
println(a === a) // 輸出“true”
val boxedA: Int? = a
val anotherBoxedA: Int? = a
println(boxedA === anotherBoxedA) // !??!輸出“true”?。?!
}
?? 上面的代碼中,a的值不同,造成的結(jié)果也不同;查看一下Kotlin編譯出的Java字節(jié)碼,選中IDEA上面菜單欄的 Tools —> Kotlin —> Show Kotlin Bytecode,在打開的Kotlin Bytecode窗口中點(diǎn)擊 Decompile

??上面代碼編譯成字節(jié)碼后,對(duì)應(yīng)的代碼如下
public final void testPacking() {
int a = 10000;
boolean var2 = true;
System.out.println(var2);
Integer boxedA = Integer.valueOf(a);
Integer anotherBoxedA = Integer.valueOf(a);
boolean var4 = boxedA == anotherBoxedA;
System.out.println(var4);
}
public final void testPacking2() {
int a = 100;
boolean var2 = true;
System.out.println(var2);
Integer boxedA = Integer.valueOf(a);
Integer anotherBoxedA = Integer.valueOf(a);
boolean var4 = boxedA == anotherBoxedA;
System.out.println(var4);
}
??果不其然,是通過 Integer 將數(shù)字進(jìn)行了裝箱操作,但是兩個(gè)數(shù)值得到的值確實(shí)不一樣的,查看Integer.valueOf()的源碼:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
發(fā)現(xiàn)i的值在-128到127之間時(shí),是從IntegerCache.cache中拿的,而不在該范圍則是每次創(chuàng)建一個(gè)Integer對(duì)象
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
// 省略部分代碼......
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
所以Kotlin文檔的示例代碼中說的不一定保留同一性,表示的是數(shù)字范圍在[-128, 127],引用相同,其他不同