Java源碼解讀(一) 8種基本類型對應的封裝類型

提及源碼其實第一個要看的應該是咱們的父類Object,這裏就不對它進行描述了你們各自對其進行閱讀便可(其中留意wait()方法可能會存在虛假喚醒的狀況)。緩存

1、八種基本類型

接下來介紹咱們的八種基本類型(這個你們都知道吧):char、byte、short、int、long、float、double、boolean。這裏也不太描述其過多的東西,只說些要特別注意的事項(若是我這存在遺落的,歡迎你們補充):eclipse

一、byte、short、char 不能進行含有變量的運算符運算(正常的運算符),都要求進行強轉,由於都有範圍限制。
 可是能夠進行+= 和自增增減的操做。
二、自動轉型等級:byte,short,char(同級)-> int -> long -> float -> double (由低精度到高精度),同級不能自動轉型,須要強制轉換
 

2、八種封裝類型

先說共同點:ui

  • equals方法:
  只有同一類型的才能做比較,而後再比較其值。源碼以short爲例,其它幾個都同樣。
    public boolean equals(Object obj) {
        if (obj instanceof Short) {
            return value == ((Short)obj).shortValue();
        }
        return false;
    }
  因此不一樣類型的無論值是否相等都是false;
    @Test
    public void testEquals(){
        Short num1 = 1;
        Integer num2 = 1;
        Long num3 = 1L;
        System.out.println(num1.equals(num2));//false
        System.out.println(num2.equals(num3));//false
    }
  •  直接賦值時,都會調用valueOf方法。因此要注意其的源代碼。
不一樣點:
一、Character
  • 注意valueOf中代碼,它緩存了ASCII碼0~127的字符。其餘均會建立實例。

 
二、Byte
  • 範圍是-128~127,因此超過這個範圍會要求強制轉換。若是使用Byte(String s)建立實例的話,超過範圍會拋出異常:NumberFormatException
  • 注意valueOf中的代碼,它緩存了-128~127,因此直接賦值是不建立新實例的。
    @Test
    public void testByte(){
        //byte的範圍是-128~127,針對byte若是賦值不在範圍eclipse會要求強制轉型成byte.
        //封裝類型Byte  new Byte("128")當使用字符串建立實例時,其中值超過範圍會報錯NumberFormatException。
        byte b1 = 12;
        Byte b2 = 12;//(byte)129;//超過範圍要求強轉
        Byte b3 = 12;//(byte)129;
        //Byte b4 = new Byte("128");//拋出異常
        Byte b4 = new Byte("12");//拋出異常
        System.out.println(b1 == b2);//true
        System.out.println(b2 == b3);//true
        System.out.println(b2 == b4);//false
    }
 
三、Short
  • 跟byte的第一點同樣,只是範圍(-32768 ~ 32767)不同
  • 注意valueOf方法,它緩存了-128~127的值,超過這個範圍(-128~127)就會建立新的實例。
  • 基於第二種狀況,不便於進行循環遍歷複製操做,不然超過範圍就會多個實例,影響內存。
    @Test
    public void testShort(){
        //一、short範圍:-32768 ~ 32767
        Short s = new Short("32767");//超過範圍會報錯 NumberFormatException
        s = new Short((short)327671);//超過這個範圍自動轉換
        
        //二、裝箱與拆箱 自動轉型
        short s1 = 12;
        Short s2 = new Short(s1);//手動裝箱
        System.out.println("s1 == s2:" + (s1 == s2));//自動拆箱  true
        
        //三、valueOf方法緩存了-128~127的範圍,超過這個範圍就要另外建立這個實例。
        Short s3 = 12;
        Short s4 = 12;
        Short s5 = 128;
        Short s6 = 128;
        System.out.println("s3 == s4:" + (s3 == s4)); //true
        System.out.println("s5 == s6:" + (s5 == s6)); //false
        
        //四、因爲上面這個特性,因此這種包裝類型不能在循環遍歷中賦值。否則其值超過這個範圍的話,就會建立新的對象,若是不少的話,就會建立不少對象。浪費空間。
    }
 
四、Integer
  • 承受的值要注意範圍(-2147483648 ~ 2147483647 ),不要求強轉。
  • 注意valueOf方法,跟Short的方法同樣,緩存了-128~127的值,超過這個範圍(-128~127)就會建立新的實例。
  • 基於第二種狀況,不便於進行循環遍歷複製操做,不然超過範圍就會多個實例,影響內存。
       @Test
        public void testInteger(){
            //一、Integer範圍:-2147483648  ~ 2147483647 
            //後面與Short同樣
            //二、裝箱與拆箱 自動轉型
            int s1 = 12;
            Integer s2 = new Integer(s1);//手動裝箱
            System.out.println("s1 == s2:" + (s1 == s2));//自動拆箱 true
            
            //三、valueOf方法緩存了-128~127的範圍,超過這個範圍就要另外建立這個實例。
            Integer s3 = 12;
            Integer s4 = 12;
            Integer s5 = 128;
            Integer s6 = 128;
            System.out.println("s3 == s4:" + (s3 == s4));//true
            System.out.println("s5 == s6:" + (s5 == s6));//false
            //四、因爲上面這個特性,因此這種包裝類型不能在循環遍歷中賦值。否則其值超過這個範圍的話,就會建立新的對象,若是不少的話,就會建立不少對象。浪費空間。
        }
 
五、Long
  • 承受的值要注意範圍(-9223372036854775808 ~ 9223372036854775807 ),不要求強轉。
  • 注意valueOf方法,跟Short的方法同樣,緩存了-128~127的值,超過這個範圍(-128~127)就會建立新的實例。
  • 基於第二種狀況,不便於進行循環遍歷複製操做,不然超過範圍就會多個實例,影響內存。
        @Test
        public void testLong(){
            //範圍就不考慮了。
            //一樣、valueOf方法緩存了-128~127的範圍,超過這個範圍就要另外建立這個實例。
            Long s3 = 12L;
            Long s4 = 12L;
            Long s5 = 128L;
            Long s6 = 128L;
            System.out.println("s3 == s4:" + (s3 == s4));//true
            System.out.println("s5 == s6:" + (s5 == s6));//false
            //因爲上面這個特性,因此這種包裝類型不能在循環遍歷中賦值。否則其值超過這個範圍的話,就會建立新的對象,若是不少的話,就會建立不少對象。浪費空間。
        } 
六、Float
  • 承受的值要注意範圍(-1.4E-45~ 3.4028235E38),不要求強轉。
  • 注意valueOf方法,跟前面的Short、Integer、Long不同了,直接建立實例。  
  • 因此相等值的兩個變量 ==運算是false.
  • 不要作加減法運算。精度(9位)問題。
    @Test
    public void testFloat(){
        //沒有特殊要注意的,其餘跟上面同樣
        int f = 1;
        Float f1 = 1F;
        Float f2 = new Float(f);
        System.out.println(f == f1);//true
        System.out.println(f1 == f2);//false
        //注意不要用這類型作加減運算,精度問題會影響。
        System.out.println(f1 - 0.1f*9);//0.099999964
    }
 
七、Double
  • 承受的值要注意範圍,不要求強轉。
  • 注意valueOf方法,與float同樣,直接建立實例。
  因此相等值的兩個變量 ==運算是false.
  • 不要作加減法運算。精度(17位)問題。
    @Test
    public void testDouble(){
        //注意不要用這類型作加減運算,精度問題會影響。
        System.out. println(1.0 - 0.1*9);//0.09999999999999998
        //valueof 
        Double i1 = 100.0;
        Double i2 = 100.0;
        Double i3 = 200.0;
        Double i4 = 200.0;
        System.out.println(i1==i2);//false
        System.out.println(i3==i4);//false
    }
八、Boolean
  • valueof方法

 

  緩存了兩個方法,因此若是是一樣的賦值,== 運算是爲true的。
    @Test
    public void testEquals(){
        Short num1 = 1;
        Integer num2 = 1;
        Long num3 = 1L;
        System.out.println(num1.equals(num2));//false
        System.out.println(num2.equals(num3));//false
    }

 3、案例分析

  猜猜下面各個輸出的結果是什麼:spa

@Test
    public void test1(){
        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));
    }

  其中會涉及到拆箱與裝箱(自行弄懂)的問題。針對個別解析以下:3d

  c==(a+b) :a+b都會拆箱成int而後相加,因此c也會自動拆箱比較。code

  g==(a+b):同理,a+b都會拆箱成int而後相加,g會拆箱成long類型。因此基本類型比較只要比較其值便可。orm

  g.equals(a+b):先拆箱a+b再裝箱仍是Integer,這裏不會自動轉型。Long類型的equals判斷不是同一類型直接返回false對象

  g.equals(a+h):同上,先拆箱a+h再裝箱(這裏會自動向上轉型)爲Long,因此同類型的比較值又相等,這裏返回true.blog

  最終結果以下:ip

true
false
true
true
true
false
true

 

相關文章
相關標籤/搜索