Java封神之路-拿下Byte

台上一分鐘,台下十年功

每當看到資深工程師寫代碼或是分享自己的心得的時候,內心無比仰慕,驚嘆大牛們為什麼能把技術研究的如此之透徹。就好比,電視劇電影里,我們見過太多了武林高手一出場,那必定是能放出大招扭轉乾坤,讓人振奮不已。
但是坐下來靜靜想想,各個行業各路精英的每一次光彩綻放,背後應該都是有大量的練習和思考,這個過程並不那麼光芒萬丈,甚至還有些枯燥。
同樣,如果想在Java這條路上封神,且不說封神,起碼讓自己對底層實現了解更加透徹,也是需要花費大量時間,下面就對今天看的內容做一個總結。主要看了java基本類庫下的java.lang.Byte。

Byte

繼承關係

可以看出,Byte繼承了Number類,實現了Comparable介面

Advertisements

成員和方法:

Byte的取值範圍從-128~127,為什麼是這個區間,這是Java的基礎。

小補充
概念:java中用補碼錶示二進位數,補碼的最高位是符號位,最高位為「0」表示正數,最高位為「1」表示負數。
正數補碼為其本身;
負數補碼為其絕對值各位取反加1;
例如:
+21,其二進位表示形式是00010101,則其補碼同樣為00010101
-21,按照概念其絕對值為00010101,各位取反為11101010,再加1為11101011,即-21的二進位表示形式為11101011
步驟:

  • byte為一位元組8位,最高位是符號位,即最大值是01111111,因正數的補碼是其本身,即此正數為01111111
    十進位表示形式為127

    Advertisements

  • 最大正數是01111111,那麼最小負是10000000(最大的負數是11111111,即-1)

  • 10000000是最小負數的補碼錶示形式,我們把補碼計算步驟倒過來就即可。10000000減1得01111111然後取反10000000
    因為負數的補碼是其絕對值取反,即10000000為最小負數的絕對值,而10000000的十進位表示是128,所以最小負數是-128

  • 由此可以得出byte的取值範圍是-128到+127

    toString方法

    public static String toString(byte b) { return Integer.toString((int)b, 10);}

    該方法返回String類型的對象。默認將byte類型的參數強轉為int類型,在10進位下的String類型的對象。

    內部靜態類ByteCache

    private static class ByteCache { private ByteCache(){} static final Byte cache[] = new Byte[-(-128) + 127 + 1]; static { for(int i = 0; i < cache.length; i++) cache[i] = new Byte((byte)(i - 128)); }}

    這個很有意思,這是將Byte的最小最大取值都裝進一個Byte類型的緩存數組。
    靜態初始化代碼塊在第一次類被載入的時候執行,可以看到通過遍歷cache的長度,分別將-128到127共256個長度的數值塞入數組
    這個數組只會創建一次,後面每次使用都不用創建這個數組,這樣做更加節省內存。
    這個ByteCache是如何調用的。下面我們看看valueOf方法

    valueOf方法

    public static Byte valueOf(byte b) { final int offset = 128; return ByteCache.cache[(int)b + offset];}

    該方法主要是返回一個byte類型對應的包裝類型。
    寫一個測試方法,看看valueOf方法是如何使用巧妙使用ByteCache的

    private static void testByte() { System.out.println(Byte.toString(Byte.MAX_VALUE)); byte byteA = 1; byte byteB = 2; byte byteC = (byte)(byteA + byteB); System.out.println(Byte.valueOf(byteC));}

    通過調試我們可以發現

  • 程序運行到Byte.valueOf方法后,內部就會調用ByteCache類的cache方法

  • 進入ByteCache類,會初始化一個 static final類型的cache數組

  • 在靜態代碼塊中,為數組賦值
    當cache數組賦值完成,這時候我們看到數組大概張這樣

  • 測試代碼傳入的參數是3,這時候在valueOf方法中會加入一個偏移量,因為cache數組是從0開始的,要想數組的下標和數組的值保持一致,需要加上偏移量128,[(int)b+ offset]正好是131,而緩存數組cache[131]的值正好是3,所以返回Byte類型的3.


    小補充:這裡為什麼使用[(int)b + offset]而不是[b + offset]
    因為在Java中的byte,short,char進行計算時都會提升為int類型,所以這裡需要強轉為int類型。
    如果你寫下面一段代碼是不能編譯通過的

    byte a = 1;byte b = 2;byte c= a + b;

    這裡寫成這樣就可以通過編譯byte c = (byte)(a + b);(a +b)在相加的時候會自動提升為int,需要強轉為byte再賦值給c。

    parseByte方法

    與Integer中的valueOf和parseInt存在調用關係不同,Byte中的valueOf並沒有調用parseByte方法,而是直接使用了緩存數組。
    parseByte就是將String類型的字元轉為byte基本類型,注意這裡沒有轉為包裝類型Byte。

    byteValue intValue longValue shortValue floatValuedoubleValue

    作為一個byte返回該byte的值。這些方法都是繼承自Number類。進入Number類,我們發現這裡並沒有booleanValue,charValue。
    因為進入Boolean和Character我們發現,這兩個包裝類都沒有繼承自Number。

Advertisements

你可能會喜歡