基本數(shù)據(jù)類型
Java 基本數(shù)據(jù)按類型可以分為四大類:布爾型膝但、整數(shù)型、浮點型汗销、字符型,這四大類包含 8 種基本數(shù)據(jù)類型抵窒。
布爾型:boolean
整數(shù)型:byte弛针、short、int李皇、long
浮點型:float削茁、double
字符型:char
8 種基本類型取值如下:
數(shù)據(jù)類型代表含義默認值取值包裝類
boolean布爾型false0(false) 到 1(true)Boolean
byte字節(jié)型(byte)0﹣128 到 127Byte
char字符型'\u0000'(空)'\u0000' 到 '\uFFFF'Character
short短整數(shù)型(short)0-215215 到 215215
﹣1Short
int整數(shù)型0﹣231231 到 231231﹣1Integer
long長整數(shù)型0L﹣263263 到 263263﹣1Long
float單浮點型0.0f1.4e-45 到 3.4e+38Float
double雙浮點型0.0d4.9e-324 到 1.798e+308Double
除 char 的包裝類 Character 和 int 的包裝類 Integer 之外,其他基本數(shù)據(jù)類型的包裝類只需要首字母大寫即可掉房。包裝類的作用和特點茧跋,本文下半部分詳細講解。
我們可以在代碼中卓囚,查看某種類型的取值范圍瘾杭,代碼如下:
public static void main(String[] args) {
?? // Byte 取值:-128 ~ 127
?? System.out.println(String.format("Byte 取值:%d ~ %d", Byte.MIN_VALUE, Byte.MAX_VALUE));
?? // Int 取值:-2147483648 ~ 2147483647
?? System.out.println(String.format("Int 取值:%d ~ %d", Integer.MIN_VALUE, Integer.MAX_VALUE));
}
包裝類型
我們知道 8 種基本數(shù)據(jù)類型都有其對應的包裝類,因為 Java 的設計思想是萬物既對象哪亿,有很多時候我們需要以對象的形式操作某項功能富寿,比如說獲取哈希值(hashCode)或獲取類(getClass)等。
那包裝類特性有哪些锣夹?
1. 功能豐富
包裝類本質(zhì)上是一個對象,對象就包含有屬性和方法苏潜,比如 hashCode银萍、getClass 、max恤左、min 等贴唇。
2. 可定義泛型類型參數(shù)
包裝類可以定義泛型,而基本類型不行飞袋。
比如使用 Integer 定義泛型戳气,代碼:
List<Integer> list = new ArrayList<>();
如果使用 int 定義就會報錯,代碼:
List list = new ArrayList<>();? // 編譯器代碼報錯
3. 序列化
因為包裝類都實現(xiàn)了 Serializable 接口巧鸭,所以包裝類天然支持序列化和反序列化瓶您。比如 Integer 的類圖如下:
4. 類型轉換
包裝類提供了類型轉換的方法,可以很方便的實現(xiàn)類型之間的轉換,比如 Integer 類型轉換代碼:
String age = "18";
int ageInt = Integer.parseInt(age) + 2;
// 輸出結果:20
System.out.println(ageInt);
5. 高頻區(qū)間的數(shù)據(jù)緩存
此特性為包裝類很重要的用途之一呀袱,用于高頻區(qū)間的數(shù)據(jù)緩存贸毕,以 Integer 為例來說,在數(shù)值區(qū)間為 -128~127 時夜赵,會直接復用已有對象明棍,在這區(qū)間之外的數(shù)字才會在堆上產(chǎn)生。
我們使用 == 對 Integer 進行驗證寇僧,代碼如下:
public static void main(String[] args) {
? ? ?? // Integer 高頻區(qū)緩存范圍 -128~127
? ? ?? Integer num1 = 127;
? ? ?? Integer num2 = 127;
? ? ?? // Integer 取值 127 == 結果為 true(值127 num1==num2 => true)
? ? ?? System.out.println("值127 num1==num2 => " + (num1 == num2));
? ? ?? Integer num3 = 128;
? ? ?? Integer num4 = 128;
? ? ?? // Integer 取值 128 == 結果為 false(值128 num3==num4 => false)
? ? ?? System.out.println("值128 num3==num4 => " + (num3 == num4));
?? }
從上面的代碼很明顯可以看出摊腋,Integer 為 127 時復用了已有對象,當值為 128 時嘁傀,重新在堆上生成了新對象兴蒸。
為什么會產(chǎn)生高頻區(qū)域數(shù)據(jù)緩存?我們查看源碼就能發(fā)現(xiàn)“線索”心包,源碼版本 JDK8类咧,源碼如下:
public static Integer valueOf(int i) {
? if (i >= IntegerCache.low && i <= IntegerCache.high)
?? return IntegerCache.cache[i + (-IntegerCache.low)];
? return new Integer(i);
}
由此可見,高頻區(qū)域的數(shù)值會直接使用已有對象蟹腾,非高頻區(qū)域的數(shù)值會重新 new 一個新的對象痕惋。
各包裝類高頻區(qū)域的取值范圍:
Boolean:使用靜態(tài) final 定義,就會返回靜態(tài)值
Byte:緩存區(qū) -128~127
Short:緩存區(qū) -128~127
Character:緩存區(qū) 0~127
Long:緩存區(qū) -128~127
Integer:緩存區(qū) -128~127
包裝類的注意事項
int 的默認值是 0娃殖,而 Integer 的默認值是 null值戳。
推薦所有包裝類對象之間的值比較使用 equals() 方法,因為包裝類的非高頻區(qū)數(shù)據(jù)會在堆上產(chǎn)生炉爆,而高頻區(qū)又會復用已有對象堕虹,這樣會導致同樣的代碼,因為取值的不同芬首,而產(chǎn)生兩種截然不同的結果赴捞。代碼示例:
public static void main(String[] args) {
?? // Integer 高頻區(qū)緩存范圍 -128~127
?? Integer num1 = 127;
?? Integer num2 = 127;
?? // Integer 取值 127 == 結果為 true(值127 num1==num2 => true)
?? System.out.println("值127 num1==num2 => " + (num1 == num2));
?? Integer num3 = 128;
?? Integer num4 = 128;
?? // Integer 取值 128 == 結果為 false(值128 num3==num4 => false)
?? System.out.println("值128 num3==num4 => " + (num3 == num4));
?? // Integer 取值 128 equals 結果為 true(值128 num3.equals(num4) => true)
?? System.out.println("值128 num3.equals(num4) => " + num3.equals(num4));
}
Float 和 Double 不會有緩存,其他包裝類都有緩存郁稍。
Integer 是唯一一個可以修改緩存范圍的包裝類赦政,在 VM optons 加入?yún)?shù):
-XX:AutoBoxCacheMax=666 即修改緩存最大值為 666 。
示例代碼如下:
public static void main(String[] args) {
?? Integer num1 = -128;
?? Integer num2 = -128;
?? System.out.println("值為-128 => " + (num1 == num2));
?? Integer num3 = 666;
?? Integer num4 = 666;
?? System.out.println("值為666 => " + (num3 == num4));
?? Integer num5 = 667;
?? Integer num6 = 667;
?? System.out.println("值為667 => " + (num5 == num6));
}
執(zhí)行結果如下:
值為-128 => true
值為666 => true
值為667 => false
由此可見將 Integer 最大緩存修改為 666 之后耀怜,667 不會被緩存恢着,而 -128~666 之間的數(shù)都被緩存了。