以下源碼基於JDK8。
舉個例子
short s1 = 1;
s1 = s1 + 1;有什麼錯?
short s1 = 1;
s1 += 1; 有什麼錯?
複製代碼
-
對於
short s1 = 1; s1 = s1 + 1;
由於s1+1
運算時會自動提升表達式的類型,所以結果是int
型,再賦值給short
類型s1
時,編譯器將報告需要強制轉換類型的錯誤。 -
對於
short s1 = 1; s1 += 1;
由於+=
是java
語言規定的運算符,java
編譯器會對它進行特殊處理,s1 = (short) (s1 + 1);
因此 可以正確編譯。
不用看了,這裏沒有表情包。
再舉個例子
public class TypeConvert {
public static void main(String[] args) {
// 字面量屬於 double 類型
// 不能直接將 1.1 直接賦值給 float 變量,因爲這是向下轉型
// Java 不能隱式執行向下轉型,因爲這會使得精度降低。
// float f = 1.1; // 這裏會報錯
float f = 1.1f;
}
}
複製代碼
不用看了,這裏也沒有表情包。
Integer的緩存池
public class IntegerPackDemo {
public static void main(String[] args) {
Integer x = 3; // 裝箱,3自動包裝爲Integer
int z = x; // 拆箱 x 拆箱爲基本類型
Integer y = 3;
System.out.println(x == y); // true 基本類型比較可用==
// -------------------------
Integer a = new Integer(3);
Integer b = new Integer(3);
System.out.println(a == b); // false 老生常談了,就不說爲什麼了
System.out.println(a.equals.(b)); // true // 這裏是用重寫了equals方法,比較的是值,而不是對象的地址
// ------------------------
// 緩存池
Integer aa = Integer.valueOf(123);
Integer bb = Integer.valueOf(123);
System.out.println(aa == bb); // true
}
}
複製代碼
別慌
Integer的equals
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue(); // 這裏比的就是值了
}
return false;
}
複製代碼
valueOf源碼
// 源碼描述:
// This method will always cache values in the range -128 to 127,
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high) // 條件
return IntegerCache.cache[i + (-IntegerCache.low)];// 取緩存,
// Integer的源碼中:
// static final int high; 127
// static final int low = -128; 因此,IntegerCache.low = -128
return new Integer(i);
}
複製代碼
IntegerCache源碼較長,有興趣可以去源碼閱讀一波
當使用自動裝箱方式創建一個Integer對象時,當數值在-128 ~127時,會將創建的 Integer 對象緩存起來,當下次再出現該數值時,直接從緩存中取出對應的Integer對象。所以上述代碼中,x和y引用的是相同的Integer對象。