第十一天 自動裝箱拆箱

基本數據類型:

在實際程序使用中,程序界面上用戶輸入的數據都以字符串類型進行存儲的.而在程序開發中,我們需呀把字符串數據抓換爲指定的基本數據類型,如年齡需要轉換爲int類型

其實是java早年設計的一個缺陷,基本數據類型不是對象,自然不是Object的子類,需要裝箱才能把數據類型變成一個類,那就可以把裝箱過後的基本數據類型當做一個對象,就可以調用object子類的接口。而且基本數據類型是不可以作爲形參使用的,裝箱後就可以。而且在jdk1.5之後就實現了自動裝箱拆箱,包裝數據類型具有許多基本數據類型不具有的功能,只是裝箱拆箱過程會稍稍微的影響一下效率,不過基本是看不出來的

 

八種包裝類

除了Char對應Character int對應的是Integer 其他都是基本數據類型的首字母大寫

這八種包裝類所繼承的父類不全都相同。

Integer ,Byte,Float,Double,Short,Long都屬於Number類的子類,Number類本身提供了一 系列的返回

Character屬於Object子類。

Boolean屬於Object子類。

裝箱和拆箱

    public static void main(String args[]){

        int a = 1;        // 基本數據類型

        Integer i = new Integer(a) ;    // 裝箱:將基本數據類型變爲包裝類

        int temp = i.intValue()    ;// 拆箱:將一個包裝類變爲基本數據類型

    }

自動拆箱和裝箱

Jdk1.5以後增加了自動拆箱和和自動裝箱功能.

 public static void main(String args[]){

        Integer i = 1 ;    // 自動裝箱成Integer

        int a = i ;            // 自動拆箱爲int

    }

而不需要手動的實現

執行Integer i = 1; 
系統爲我們執行了: 
Integer i = Integer.valueOf(1);

執行int a = i; 
系統爲我們執行了: 
int a = i.intValue();

 

看下源碼jdk1.8

    public static Integer valueOf(int i) {

        if (i >= IntegerCache.low && i <= IntegerCache.high)

            return IntegerCache.cache[i + (-IntegerCache.low)];

        return new Integer(i);

    }

對於128127之間的值,Integer.valueOf(int i) 返回的是緩存的Integer對象,超出範圍的則是新new一個對象,IntegerCachenymber的一個靜態內部類,就在下面

 

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.

                }

            }

            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() {}

    }

 

//-128~127 之外的數

 Integer i1 =200;  

 Integer i2 =200;          

 System.out.println("i1==i2: "+(i1==i2));                

 // -128~127 之內的數

 Integer i3 =100;  

 Integer i4 =100;  

 System.out.println("i3==i4: "+(i3==i4));   

結果 false

True

簡單來說就是數據在byte(-128~127)範圍內,JVM不會從新new對象

對於IntegerShortByteCharacterLong這幾個類的valueOf方法的實現是類似的。也就是說上面的結果都是成立的

對於DoubleFloatvalueOf方法的實現是類似的。他們沒有內部類的,valueof方法與上面的不同,他們每次賦值都會在堆內存中創建新對象

 

public class Main {

    public static void main(String[] args) {

         

        Boolean i1 = false;

        Boolean i2 = false;

        Boolean i3 = true;

        Boolean i4 = true;

         

        System.out.println(i1==i2);

        System.out.println(i3==i4);

    }

}

True

True

可以去研究下boolean類的源碼

 

 

當然,當不使用自動裝箱功能的時候,情況與普通類對象一樣

 Integer i1 =new Integer(100);

 Integer i2 =new Integer(100);

 System.out.println((i1==i2));

False

因爲他們沒有觸發自動裝箱.也就會直接在new出來新的對象

 

Integer i = new Integer(?)Integer i =?區別

第一種不會觸發自動裝箱,第二種會觸發

在執行效率和資源上,第二種的執行效率和內存佔用會小於第二種.(而且這不是絕對的)

 

一道題

public class Main {  

    public static void main(String[] args) {  

           

        Integer a = 1;  

        Integer b = 2;  

        Integer c = 3;  

        Integer d = 3;  

        Integer e = 321;  

        Integer f = 321;  

        Long g = 3L;  

        Long h = 2L;  

           

        System.out.println(c==d);  

        System.out.println(e==f);

        System.out.println(c==(a+b));  

        System.out.println(c.equals(a+b));  

        System.out.println(g==(a+b));  

        System.out.println(g.equals(a+b));  

        System.out.println(g.equals(a+h));     

}  

}  

 

true

false

true

true

true

false

True

 

包裝類的==運算在不遇到算術運算的情況下不會自動拆裝

.也就是說沒遇到算數運算就比較是否是指向同一對象,如果有算數運算就比較數值(觸發自動裝箱拆箱)

 

包裝器類型equals方法不會處理數據轉換的類型,

 

注意最後一個

對於a+h,先自動觸發拆箱,就變成了int類型和long類型相加,這個會觸發類型晉升,結果是long類型的,然後會觸發裝箱過程,就變成Long了。因此比較結果是true

 

倒數第二個是兩個integer類型沒有類型提升所以是false

 

 

類中的幾個方法

Integer類的parseInt

A.  parseInt()

    int i = Integer.parseInt("2");

    System.out.println(i/2);//1

B.  parseInt(String s,int radix)

指定進制的字符串轉換爲十進制的整數

Public static void function(){

Int i  = IntegerInt(110,2);//前面的數是二進制的

System.out.println(i);

}

不想在寫方法了感覺不知道這些常用類要掌握到什麼地步,用的時候查API不就好了碼 ,掌握到什麼地步才行,要有多熟練.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章