1、包裝類簡介 我們都知道Java是面向對象編程語言,包含了8種基本數據類型,但是這8種基本數據類型並不支持面向對象的特征,它們既不是類,也不能調用方法。這在實際使用時存在很多的不便,比如int類型需要轉換成字元串,為瞭解決這個不足。然後就出現了包裝類,顧名思義,就是將這些基本數據類型封裝在類中,並 ...
1、包裝類簡介
我們都知道Java是面向對象編程語言,包含了8種基本數據類型,但是這8種基本數據類型並不支持面向對象的特征,它們既不是類,也不能調用方法。這在實際使用時存在很多的不便,比如int類型需要轉換成字元串,為瞭解決這個不足。然後就出現了包裝類,顧名思義,就是將這些基本數據類型封裝在類中,並且提供豐富的方法來對數據進行操作。這樣八個和基本數據類型對應的類統稱為包裝類(Wrapper Class)。
Java中的包裝類提供了將基本數據類型轉換為對象,以及將對象轉換為基本數據類型的機制。
其中Byte,Short,Integer,Float,Double,Long都屬於Number子類。Character ,Boolean屬於Object子類。它們的預設值都是NULL。
2、基本數據類型、包裝類、字元串之間的轉換
①、基本數據類型轉換為包裝類(裝箱):調用包裝類的構造器
//基本數據類型——>包裝類:調用包裝類的構造器 @Test public void test1(){ int num=10; Integer i1=new Integer(num); System.out.println("i1結果:"+i1); Integer i2=new Integer("10"); System.out.println("i2結果:"+i2); //報錯,必須是純數字,java.lang.NumberFormatException: For input string: "10abc" //Integer i3=new Integer("10abc"); //System.out.println(i3); Double d1=new Double(12.3); Double d2=new Double("12.3"); System.out.println("d1結果:"+d1); System.out.println("d1結果:"+d2); Boolean b1=new Boolean(true); Boolean b2=new Boolean("TrUe"); Boolean b3=new Boolean("TrUe123"); System.out.println("b1結果:"+b1); System.out.println("b2結果:"+b2); System.out.println("b3結果:"+b3); }
運行結果:
從運行的結果來看,通過調用包裝類構造器可以將基本數據類型轉為包裝類,但是傳入的參數必須合法,否則就像Integer那樣會報錯。可以看見Boolean包裝類傳入的字元串是忽略大寫的,這是因為構造器中調用了parseBoolean(String s)方法,然後這個方法內部又調用了String方法的equalsIgnoreCase(String anotherString)方法,所以傳入字元串會忽略大小寫。而且你傳入的是非法字元串它並不會報錯,只是返回了false,這裡需要註意一下。
②、包裝類轉換為基本數據類型(拆箱):調用包裝類的Xxx的xxxValue()方法
//包裝類——>基本數據類型:調用包裝類的Xxx的xxxValue()方法 @Test public void test2(){ Integer integer = new Integer(10); int i=integer.intValue(); System.out.println(i+1); Double aDouble = new Double(10.11); double d=aDouble.doubleValue(); System.out.println(d+1); Boolean aBoolean = new Boolean(false); boolean b=aBoolean.booleanValue(); System.out.println(b); }
運行結果:
包裝類轉換為基本數據類型是非常簡單的,只需要調用正確的方法即可,其他的包裝類也是同樣的道理。
你會發現前面兩個點這樣換來換去會非常的麻煩,其實從JDK5之後就變得非常簡單了,這就要到後面介紹自動拆箱和自動裝箱。
③、由於出現了自動拆箱和自動裝箱,基本數據類型和包裝類就可以看成一個整體。
基本數據類型、包裝類轉換為字元串:調用String重載的valueOf(Xxx xxx)
//基本數據類型、包裝類->字元串:調用String重載的valueOf(Xxx xxx) @Test public void test3(){ int num=10; //方式1:連接運算 String str1=num+""; System.out.println("str1結果"+str1); //方式2:調用String的valueOf(Xxx xx)方法 int num1=15; String str2=String.valueOf(num1); System.out.println("str2結果"+str2); Integer integer=new Integer(21); String str3=String.valueOf(integer); System.out.println("str3結果"+str3); }
運行結果:
④、字元串轉換為基本數據類型、包裝類:調用包裝類中的parseXxx()方法
//字元串——>基本數據類型、包裝類:調用包裝類中的parseXxx()方法; @Test public void test5(){ String str1="211"; int num=Integer.parseInt(str1); System.out.println(num); //運行報錯,ava.lang.NumberFormatException: For input string: "211abc" //String str2="211abc"; //int num1=Integer.parseInt(str2); String str3="truetrue"; boolean b=Boolean.parseBoolean(str3); System.out.println(b); }
運行結果:211、false。
無論怎樣轉換,數據的格式必須是正確的,否則就會報錯,boolean特殊點,返回的是false。
最後它們三者的轉換可以詳細歸結為:
1、基本數據類型與包裝類之間轉換:直接使用自動裝箱和自動拆箱(後面會講到,非常簡單)。
2、基本數據類型、包裝類轉換為字元串:調用String的valueOf(Xxx xxx)方法。
3、字元串轉換為基本數據類型、包裝類:調用包裝類的parseXxx()方法。
另外包裝類中還有豐富的方法可供大家調用,如需學習可以自行查看包裝類的API。
3、自動拆箱和自動裝箱
將基本數據類型變成包裝類稱為裝箱,將包裝類的類型變為基本數據類型稱為拆箱。
在JDK1.5之後,Java提供了自動裝箱和自動拆箱功能。
下麵來看一下案例:
@Test public void test6(){ int i=21; Integer integer=i;//自動裝箱 int j=integer;//自動拆箱 double d=21.11; Double aDouble=d; double e=aDouble; }
由於出現了自動裝箱和自動拆箱功能,所以基本數據類型和包裝類之間的相互轉換變得非常簡單,再也不用去調用繁瑣的方法了。
但是也會出現一些特殊的情況,案例如下:
@Test public void test7(){ Integer a=127; Integer b=127; System.out.println(a == b); Integer c=128; Integer d=128; System.out.println(c == d); }
運行結果:
運行的結果肯定會有很大的疑問?同樣是兩個int型自動裝箱為包裝類進行比較,為什麼127比較返回是true,而128比較則返回了false。這是為什麼呢?這與Java的Integer類的設計有關,查看Integer類的源代碼,如下所示。
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; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } //將127賦給high變數 high = h; //定義長度為256的Integer數組 cache = new Integer[(high - low) + 1]; int j = low; //執行初始化,創建-128~127的Integer實例,並放入cache[]數組中 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() {} }
從上面代碼可以看出,Integer類中定義了一個IntegerCache內部類,內部類中定義了一個靜態常量的Integer cache [ ]數組,而這個數組存儲了從-128~127之間的整數自動裝箱成Integer實例,如果我們使用自動裝箱的方式,給Integer包裝類賦值時,範圍在-128~127之間,就可以直接使用數組中的元素,因為-128~127之間的同一個整數自動裝箱成Integer實例時,永遠是引用cache數組的同一個數組元素。如果超出了這個範圍,自動裝箱需要再重新new對象,所以就出現了程式中的運行結果。
4、小結
1、包裝類的預設值都是NULL。
2、基本數據類型、包裝類、字元串之間的轉換可以歸結為:
- 基本數據類型與包裝類之間轉換:直接使用自動裝箱和自動拆箱。
- 基本數據類型、包裝類轉換為字元串:調用String的valueOf(Xxx xxx)方法。
- 字元串轉換為基本數據類型、包裝類:調用包裝類的parseXxx()方法。
3、Integer類中預設存放值的範圍是-128~127之間。