java源碼解讀之Integer

每天都在用着Java各種各樣的類與方法,但是也僅僅只是侷限於用,卻不瞭解那些每天都接觸的類與方法內部是如何去實現的,遇到問題只能不停地度娘谷歌看文章,因此決定從現在開始學習jdk的源碼,我相信基礎的東西永遠都不會過時,不僅要知其然,還要知其所以然。

先從我們平常用的最多的數據類型入手,最常見的莫過於Integer類型,本篇文章就對Integer的源碼常用的方法進行解讀,源碼去掉了多餘且看得一臉懵逼的英文註釋所有的分析都寫在源碼上,無需一邊看字一邊看代碼啦,下面開始放大招“祭出源碼”啦大笑

package java.lang;

import java.util.Properties;

/**
 * Integer類被final修飾,因此該類是不可被繼承
 */
public final class Integer extends Number implements Comparable<Integer> {
    /**
     * Integer 可以取到的最小值,十六進制形式爲0x80000000,二進制即爲-2147483648(-2^31)
     */
    public static final int   MIN_VALUE = 0x80000000;

    /**
     * 也就是說Integer的取值範圍是[-2147483648,2147483647],超過則溢出,需要更大的數據類型來存儲
     */
    
    /**
     * Integer 可以取到的最大值,十六進制形式爲0x7fffffff,二進制即爲2147483647(2^31-1)
     */
    public static final int   MAX_VALUE = 0x7fffffff;

    /**
     * 記錄該基本類型包裝類所對應的基本數據類型(如:Integer對應int,Double對應double等)
     */
    public static final Class<Integer>  TYPE = (Class<Integer>) Class.getPrimitiveClass("int");

    /**
     * 存放所有可能被用來代表數字的字符
     */
    final static char[] digits = {
        '0' , '1' , '2' , '3' , '4' , '5' ,
        '6' , '7' , '8' , '9' , 'a' , 'b' ,
        'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
        'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
        'o' , 'p' , 'q' , 'r' , 's' , 't' ,
        'u' , 'v' , 'w' , 'x' , 'y' , 'z'
    };

    /**
     * 以字符串的形式返回指定int類型數字對應的radix進制數的表示形式
     */
    public static String toString(int i, int radix) {

    	//若radix進制數超出指定範圍[2,36],則radix設置爲默認的10進制
        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
            radix = 10;

        /* Use the faster version */
        if (radix == 10) {
        	//若是radix進制數爲10,則直接返回即可,因爲默認就是10進制數的
            return toString(i);
        }
        //radix進制數既不是10也不超出指定範圍,則執行進制轉換的運算,用求餘運算 i%radix
        char buf[] = new char[33];
        boolean negative = (i < 0);
        int charPos = 32;
        //若該數字i爲正數,則轉換成-i,防止溢出,用負數來進行運算
        if (!negative) {
            i = -i;
        }
        //這裏循環進行求餘運算
        while (i <= -radix) {
         //由於前面將i轉換成負數,故求餘得到的餘數前面需再多個負號(負負得正嘛,數組下標總不能爲負的啦)
            buf[charPos--] = digits[-(i % radix)];
            i = i / radix;
        }
        buf[charPos] = digits[-i];
        //這裏將數字的正負還原
        if (negative) {
            buf[--charPos] = '-';
        }
        //返回數字i指定進制數的字符串  String(char value[],int start,int count)
        return new String(buf, charPos, (33 - charPos));
    }

    /**
     * 將指定int數字i轉換爲16進制數字符串
     */
    public static String toHexString(int i) {
        return toUnsignedString(i, 4);
    }

    /**
     * 將指定int數字i轉換爲8進制數字符串
     */
    public static String toOctalString(int i) {
        return toUnsignedString(i, 3);
    }

    /**
     * 將指定int數字i轉換爲2進制數字符串
     */
    public static String toBinaryString(int i) {
        return toUnsignedString(i, 1);
    }

    /**
     * 將指定int數字i轉換爲無符號的字符串
     */
    private static String toUnsignedString(int i, int shift) {
        char[] buf = new char[32];
        int charPos = 32;
        int radix = 1 << shift;//左移運算,相當於1乘以2^shift
        int mask = radix - 1;
        do {
            //與運算,i跟mask的二進制數進行與運算,用運算結果進行查表後賦值給char數組
            buf[--charPos] = digits[i & mask];
            i >>>= shift;//i進行右移後賦值運算,最高位都補0
        } while (i != 0);
        //直到i等於0以字符串形式返回計算結果   String(char value[],int start,int count)
        return new String(buf, charPos, (32 - charPos));
    }

    //存儲十位數以上的字符集,用於下面方法求餘運算快速算出十位上的數值
    final static char [] DigitTens = {
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
        '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
        '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
        '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
        '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
        '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
        '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
        '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
        '9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
        } ;
    
    //存儲個位數以上的字符集,用於下面方法求餘運算快速算出個位上的數值
    final static char [] DigitOnes = {
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        } ;

    public static String toString(int i) {
        if (i == Integer.MIN_VALUE)
            return "-2147483648";
        //確定數字i是多少位數的
        int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
        char[] buf = new char[size];
        //計算生成i要返回字符數組
        getChars(i, size, buf);
        //String(int start,int count,char[] value)
        return new String(0, size, buf);
    }

    /**
     * 當==Integer.MIN_VALUE時將轉換失敗
     * 該方法主要用了以下4個體繫結構知識(下文代碼以1,2,3,4代表):
     * 1.乘法比除法高效:除法絕大部分都以乘法+位移運算來替代,如:q = (i * 52429) >>> (16+3); 
     * 2.位移運算比乘法高效:方法中絕大部分的乘法運算都以  << 左移運算替代 
     * 3.重複利用計算結果: q = i / 100;r = i - ((q << 6) + (q << 5) + (q << 2));
     * 4.局部性原理之空間局部性:buf[--charPos] = DigitOnes[r];buf[--charPos] = DigitTens[r];
     * 通過以下標查找數組,實現快速訪問,避免除法運算
     */
    static void getChars(int i, int index, char[] buf) {
        int q, r;
        int charPos = index;
        char sign = 0;//用於記住數字i的符號,+還是-

        if (i < 0) {
            sign = '-';
            i = -i;
        }

        //對於比較大的數字,先迭代求餘,每次算出2位數的餘數放到字符緩衝區中
        while (i >= 65536) {
            //關於這裏的除法爲什麼不用乘法+位移運算來替代,是因爲進入該迭代的數值都是比較
            //大的,而int類型最大值爲(2^31-1),使用乘法+位移運算容易溢出
            q = i / 100;
            //實際上就是 r = i - (q * 100); r爲i/100的餘數   q<<6是左移運算,即爲q乘以2^6
            r = i - ((q << 6) + (q << 5) + (q << 2));//利用到了體系結構知識3
            i = q;
            ////利用到了體系結構知識4
            buf [--charPos] = DigitOnes[r];//存儲餘數r的個位數,即r%10
            buf [--charPos] = DigitTens[r];//存儲餘數r的十位數,即r/10
        }
        //對於較小數字(<= 65536)的快速計算模式
        for (;;) {
            //該表達式利用到了體系結構知識1,2^19=524288,這樣能保證在int的範圍內計算出來
            //的精度最高,即(i*52429)/524288,其中52429/524288=0.10000038146972656,
            //這也是爲什麼選擇52429餘524288這兩個數的原因
            q = (i * 52429) >>> (16+3); //實際上就是q/10
            r = i - ((q << 3) + (q << 1));  // 跟上面一樣,實際上就是 r = i-(q*10) ...
            buf [--charPos] = digits [r];//存儲個位數的餘數
            i = q;
            if (i == 0) break;
        }
        if (sign != 0) {
            buf [--charPos] = sign;
        }
    }

    final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
                                      99999999, 999999999, Integer.MAX_VALUE };

    //求數字i的位數,不用再像老師教的除以10然後幹嘛幹嘛啦
    static int stringSize(int x) {
        for (int i=0; ; i++)
            if (x <= sizeTable[i])
                return i+1;
    }

    /**
     * <p>Examples:
     * <blockquote><pre>
     * parseInt("0", 10) returns 0
     * parseInt("473", 10) returns 473
     * parseInt("+42", 10) returns 42
     * parseInt("-0", 10) returns 0
     * parseInt("-FF", 16) returns -255
     * parseInt("1100110", 2) returns 102
     * parseInt("2147483647", 10) returns 2147483647
     * parseInt("-2147483648", 10) returns -2147483648
     * parseInt("2147483648", 10) throws a NumberFormatException
     * parseInt("99", 8) throws a NumberFormatException
     * parseInt("Kona", 10) throws a NumberFormatException
     * parseInt("Kona", 27) returns 411787
     * </pre></blockquote>
     * 將指定radix進制數的字符串轉換爲10進制的int類型數字
     */
    public static int parseInt(String s, int radix)
                throws NumberFormatException
    {
    	//傳遞進來的String爲null的時候,拋NumberFormatException異常
        if (s == null) {
            throw new NumberFormatException("null");
        }
        //若要轉換的進制數不是屬於[2,36]的,則同樣拋NumberFormatException異常
        if (radix < Character.MIN_RADIX) {
            throw new NumberFormatException("radix " + radix +
                                            " less than Character.MIN_RADIX");
        }

        if (radix > Character.MAX_RADIX) {
            throw new NumberFormatException("radix " + radix +
                                            " greater than Character.MAX_RADIX");
        }

        int result = 0;
        boolean negative = false;//用於標誌該字符串數字是"+" or "-"
        int i = 0, len = s.length();
        int limit = -Integer.MAX_VALUE;
        int multmin;
        int digit;
        
        if (len > 0) {
            //取字符串s第一個字符,以判斷該字符串數字是"+" or "-"
            char firstChar = s.charAt(0);
            if (firstChar < '0') { // Possible leading "+" or "-"
                if (firstChar == '-') {
                    negative = true;
                    limit = Integer.MIN_VALUE;
                } else if (firstChar != '+')
                    throw NumberFormatException.forInputString(s);

                if (len == 1) //字符串不能只有一個字符"+" or "-"的
                    throw NumberFormatException.forInputString(s);
                i++;
            }
            multmin = limit / radix;
            /**
             * 這裏的迭代舉個例子:
             * "12345"按照十進制轉成12345的方法其實就是((1*10)+2)*10)+3)*10+4)*10+5
             * 而如何將字符串中每個字符轉換成不同進制的int類型數字則是下面
	     * Character.digit(char ch,int radix)方法的事情了
             */
            while (i < len) {
                //逐個字符累積以防止突然就接近Integer的最大值,導致溢出
            	//使用Character.digit(char ch,int radix)方法將字符串中的
		//每個字符轉換成不同進制的int類型數字
                digit = Character.digit(s.charAt(i++),radix);
                if (digit < 0) {
                    throw NumberFormatException.forInputString(s);
                }
                if (result < multmin) {
                    throw NumberFormatException.forInputString(s);
                }
                result *= radix;
                if (result < limit + digit) {
                    throw NumberFormatException.forInputString(s);
                }
                result -= digit;
            }
        } else {
            //String的長度<=0,同樣拋NumberFormatException並提示字符串信息
            throw NumberFormatException.forInputString(s);
        }
        //返回轉換後的10進制數字
        return negative ? result : -result;
    }

    /**
     * 將字符串數字轉換爲int類型數字,不填radix進制數則默認字符串s爲10進制的數字字符串
     */
    public static int parseInt(String s) throws NumberFormatException {
        return parseInt(s,10);
    }

    /**
     * 將字符串數字按照指定的radix進制數轉換成int數字
     * 先調用parseInt方法將字符串數字轉換爲int數字,再調用valueOf方法返回Integer對象
     */
    public static Integer valueOf(String s, int radix) throws NumberFormatException {
        return Integer.valueOf(parseInt(s,radix));
    }

    /**
     * 將字符串數字轉換成int數字,默認爲10進制數字
     * 先調用parseInt方法將字符串數字轉換爲10進制的int數字,再調用valueOf方法返回Integer對象
     */
    public static Integer valueOf(String s) throws NumberFormatException {
        return Integer.valueOf(parseInt(s, 10));
    }
    
    /**
     * Integer類的內部字符緩衝類,默認情況下緩衝的範圍是[-128,127],
     * 當我們使用Integer類型的數字時,若該數字處於該範圍,則其引用所指
     * 向的內存即是該緩衝區的內存,不會開闢新的內存空間,若是超過該範圍
     * 則開闢新的內存空間
     * 這也是爲什麼人們常說:java中的Integer類型100==100而1000!=1000
     * 該緩衝區的大小可以通過參數-XX:AutoBoxCacheMax來設置
     */
    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) {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low));
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
        }

        private IntegerCache() {}
    }

    /**
     * 將int數字轉換爲Integer對象
     */
    public static Integer valueOf(int i) {
        assert IntegerCache.high >= 127;
        //若int數字的值在Integer類的內部緩衝區的範圍內(即[-128,127]),
	//則直接從緩衝區返回一個已存在的Integer對象
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        //若不在緩衝區的範圍內,則new一個新的Integer對象返回
        return new Integer(i);
    }
    /**
     * 因此,當把一個int變量轉成Integer的時候(或者新建一個Integer的時候),
     * 建議使用valueOf方法來代替構造函數,
     * 或者直接使用Integer i = 100;編譯器會轉成Integer s = Integer.valueOf(10000)
     * valueOf與parseInt的差別在於valueOf可能會利用到Integer內部的緩衝區
     */

    /**這裏的value屬性是真正保存Integer對象的int值的,而且是被final修飾的,也
     * 就是說,當一個Integer對象被初始化後,value的值是無法被改變的,即一個已
     *初始化的Integer對象中的int值是不可變的,至於在我們一般的程序中Integer
     *對象的值可以重新賦值,可以看下面一個簡單的代碼例子:
     * Integer i = new Integer(10);
     * i = 5;
     * System.out.println(i);
     * 我們都知道這個打印出來的一定是5,這樣不就與我們剛剛說的Integer對象中
     *的int值是不可變的相互打臉了麼
     * 實則不然,將上面的代碼反編譯之後,會變成如下的樣子:
     * Integer i = new Integer(10);
     * i = Integer.valueOf(5);
     * System.out.println(i);
     * 即i=5會被編譯器轉換成i=Integer.valueOf(5)
     * 也就是說,i=5並沒有改變使用Integer i = new Integer(10)創建出來的Integer對
     * 象i中的value屬性的值,而是重新創建(或者從緩衝區返回)一個對象,並將引用i指
     * 向新的Integer對象,所以剛剛的說法並無打臉之處
     */
   
    private final int value;

    public Integer(int value) {
        this.value = value;
    }

    public Integer(String s) throws NumberFormatException {
        this.value = parseInt(s, 10);
    }

    public byte byteValue() {
        return (byte)value;
    }

    public short shortValue() {
        return (short)value;
    }

    public int intValue() {
        return value;
    }

    public long longValue() {
        return (long)value;
    }

    public float floatValue() {
        return (float)value;
    }

    public double doubleValue() {
        return (double)value;
    }

    public String toString() {
        return toString(value);
    }

    public int hashCode() {
        return value;
    }

    /**
     * Integer對象之間的equals其實比的就是int值,所以呢,當2個Integer對象要比較是否相等的話,要麼
     * 調用equals方法,要麼調用intValue方法(a.intValue()==b.intValue())來比較,千萬別直接就
     * 上"=="比較,之前沒注意就被這個給坑死了額
     */
    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

    /**
     * 返回具有指定名稱的系統屬性的整數值,是通過
     * System.getProperty(java.lang.String)方法可以訪問的系統屬性
     */
    public static Integer getInteger(String nm) {
        return getInteger(nm, null);
    }

    /**
     * 返回具有指定名稱的系統屬性的整數值,是通過System.getProperty(java.lang.String)
     * 方法可以訪問的系統屬性,
     * 如果沒有具有指定名稱的屬性,或者屬性的數字格式不正確,或者指定名稱爲空或null,則
     * 返回一個表示第二個參數的值的Integer對象
     */
    public static Integer getInteger(String nm, int val) {
        Integer result = getInteger(nm, null);
        return (result == null) ? Integer.valueOf(val) : result;
    }

    /**
     * 返回具有指定名稱的系統屬性的整數值,是通過
     * System.getProperty(java.lang.String)方法可以訪問的系統屬性,
     * 如果沒有具有指定名稱的屬性,或者屬性的數字格式不正確,或者指定
     * 名稱爲空或null,則返回一個表示第二個參數的對象
     */
    public static Integer getInteger(String nm, Integer val) {
        String v = null;
        try {
            //首先通過System.getProperty(String)取得指定名稱的系統屬性
            v = System.getProperty(nm);
        } catch (IllegalArgumentException e) {
        } catch (NullPointerException e) {
        }
        if (v != null) {
            try {
            	//若能去得到指定名稱的系統屬性值,則調用Integer類
		//的decode(String)方法將字符串轉換爲Integer對象
                return Integer.decode(v);
            } catch (NumberFormatException e) {
            }
        }
        return val;
    }

    public static Integer decode(String nm) throws NumberFormatException {
        int radix = 10;//默認的進制數爲10進制
        int index = 0;
        boolean negative = false;
        Integer result;

        if (nm.length() == 0)
            throw new NumberFormatException("Zero length string");
        char firstChar = nm.charAt(0);
        // Handle sign, if present
        //這裏通過字符串的第一個字符來判斷要返回的Integer是"+" or "-"的
        if (firstChar == '-') {
            negative = true;
            index++;
        } else if (firstChar == '+')
            index++;

        // Handle radix specifier, if present
        //這裏確定要將字符串轉換爲多少進制的Integer對象
        //若字符串以"0x" or "0X" 開頭,則後面將其轉換爲16進制的Integer對象
        if (nm.startsWith("0x", index) || nm.startsWith("0X", index)) {
            index += 2;
            radix = 16;
        }
        //若字符串以 "#" 開頭,則後面同樣將其轉換爲16進制的Integer對象
        else if (nm.startsWith("#", index)) {
            index ++;
            radix = 16;
        }
        //若字符串以 "0" 開頭且字符串長度大於2,則後面將其轉換爲8進制的Integer對象
        else if (nm.startsWith("0", index) && nm.length() > 1 + index) {
            index ++;
            radix = 8;
        }
        //若標誌字符串 "+" or "-"的字符出現在錯誤的位置,則拋NumberFormatException
        if (nm.startsWith("-", index) || nm.startsWith("+", index))
            throw new NumberFormatException("Sign character in wrong position");

        try {
            //這裏調用上面的valueOf方法將剩餘的字符串轉換爲指定進制數的Integer對象
            result = Integer.valueOf(nm.substring(index), radix);
            //判斷Integer對象是 "+" or "-"並返回轉換後的Integer對象
            result = negative ? Integer.valueOf(-result.intValue()) : result;
        } catch (NumberFormatException e) {
            // If number is Integer.MIN_VALUE, we'll end up here. The next line
            // handles this case, and causes any genuine format error to be
            // rethrown.
            String constant = negative ? ("-" + nm.substring(index))
                                       : nm.substring(index);
            result = Integer.valueOf(constant, radix);
        }
        return result;
    }

    /**
     * 總結下getInteger方法:這個方法是用於獲取指定名稱的系統屬
     * 性的整數值,而不是將String類型轉換爲Integer(PS:一開始
     * 我就是這麼天真的認爲的,直到看了源碼O__O "…),要將String轉
     * 換爲Integer/int請使用valueOf/parseInt方法
     * 該方法的調用棧是這樣的:
     * getInteger(String nm) ---> getInteger(nm, null);--->
     * Integer.decode()--->Integer.valueOf()--->parseInt()
     * 因此,總結下parseInt、valueOf、decode、getInteger方法:
     * 如果只需要返回一個基本類型,而不需要一個對象,可以直接使用parseInt方法;
     * 如果需要一個對象,那麼建議使用valueOf方法,因爲該方法可以藉助緩存帶來的好處;
     * 如果和進制有關,那麼就是用decode方法;
     * 如果是從系統配置中取值,那麼就是用getInteger方法
     */
    
    
    
    /**
     * Integer對象之間的比較,大於返回1,小於返回-1,等於返回0,實際上
     * 就是對Integer中基本數據類型value值的比較
     */
    public int compareTo(Integer anotherInteger) {
        return compare(this.value, anotherInteger.value);
    }

    public static int compare(int x, int y) {
        return (x < y) ? -1 : ((x == y) ? 0 : 1);
    }


    // Bit twiddling

    /**
     * The number of bits used to represent an {@code int} value in two's
     * complement binary form.
     *
     * @since 1.5
     */
    public static final int SIZE = 32;

    /**
     * 返回具有至多單個1位的 int值,在指定的int值中最高位(最左邊)的1位的位置
     */
    public static int highestOneBit(int i) {
        // HD, Figure 3-1
        i |= (i >>  1);
        i |= (i >>  2);
        i |= (i >>  4);
        i |= (i >>  8);
        i |= (i >> 16);
        return i - (i >>> 1);
    }

    /**
     * 返回具有至多單個1位的 int值,在指定的int值中最低位(最右邊)的1位的位置
     */
    public static int lowestOneBit(int i) {
        // HD, Section 2-1
        return i & -i;
    }

    /**
     * 在指定int值的二進制補碼錶示形式中最高位(最左邊)的1位之前,返回零位的數量
     */
    public static int numberOfLeadingZeros(int i) {
        // HD, Figure 5-6
        if (i == 0)
            return 32;
        int n = 1;
        if (i >>> 16 == 0) { n += 16; i <<= 16; }
        if (i >>> 24 == 0) { n +=  8; i <<=  8; }
        if (i >>> 28 == 0) { n +=  4; i <<=  4; }
        if (i >>> 30 == 0) { n +=  2; i <<=  2; }
        n -= i >>> 31;
        return n;
    }

    /**
     * 返回指定的int值的二進制補碼錶示形式中最低(最右邊)的爲1的位後面的零位個數
     */
    public static int numberOfTrailingZeros(int i) {
        // HD, Figure 5-14
        int y;
        if (i == 0) return 32;
        int n = 31;
        y = i <<16; if (y != 0) { n = n -16; i = y; }
        y = i << 8; if (y != 0) { n = n - 8; i = y; }
        y = i << 4; if (y != 0) { n = n - 4; i = y; }
        y = i << 2; if (y != 0) { n = n - 2; i = y; }
        return n - ((i << 1) >>> 31);
    }

    /**
     * 返回指定int值的二進制補碼錶示形式的1位的數量
     */
    public static int bitCount(int i) {
        // HD, Figure 5-2
        i = i - ((i >>> 1) & 0x55555555);
        i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
        i = (i + (i >>> 4)) & 0x0f0f0f0f;
        i = i + (i >>> 8);
        i = i + (i >>> 16);
        return i & 0x3f;
    }

    /**
     * 返回根據指定的位數循環左移指定的int值的二進制補碼錶示形式而得到的值
     */
    public static int rotateLeft(int i, int distance) {
        return (i << distance) | (i >>> -distance);
    }

    /**
     * 返回根據指定的位數循環右移指定的int值的二進制補碼錶示形式而得到的值
     */
    public static int rotateRight(int i, int distance) {
        return (i >>> distance) | (i << -distance);
    }

    /**
     * 返回通過反轉指 int值的二進制補碼錶示形式中位的順序而獲得的值
     */
    public static int reverse(int i) {
        // HD, Figure 7-1
        i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
        i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
        i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
        i = (i << 24) | ((i & 0xff00) << 8) |
            ((i >>> 8) & 0xff00) | (i >>> 24);
        return i;
    }

    /**
     * 返回指定int值的符號函數
     */
    public static int signum(int i) {
        // HD, Section 2-7
        return (i >> 31) | (-i >>> 31);
    }

    /**
     * 返回通過反轉指定int值的二進制補碼錶示形式中字節的順序而獲得的值
     */
    public static int reverseBytes(int i) {
        return ((i >>> 24)           ) |
               ((i >>   8) &   0xFF00) |
               ((i <<   8) & 0xFF0000) |
               ((i << 24));
    }

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = 1360826667806852920L;
}
其中,相對比較重要的方法都有比較囉嗦的註釋,其餘的知道就好啦,無需深究(其實就是我學識短淺深究不了O(∩_∩)O哈哈哈~),以上就是Integer類源碼的解讀。

銘記初衷,傾己所有微笑~~~

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