Integer源碼分析


title: Integer源碼分析
date: 2017-09-11 15:07:46
tags: java
categories: java


Integer繼承了Number類,并且實現(xiàn)了Comparable

Number類


Number類是所有數(shù)字類的基類,它是一個抽象類峭梳,并且實現(xiàn)序列化的接口

其中提供了四種抽象方法,是將對應(yīng)的value轉(zhuǎn)換成對類型的值返回

    intValue();
    longValue();
    floatValue();
    doubleValue();

Integer類

Integer實現(xiàn)了Number中的所有接口(我覺得只是提供了一種安全地的轉(zhuǎn)型)

  1. 構(gòu)造方法

Integer只提供了兩種構(gòu)造方法尚卫,一種是初始化數(shù)字四瘫,一種是使用String通過內(nèi)部的parseInt將字符轉(zhuǎn)換成數(shù)字

public Integer(int value)

public Integer(String s) throws NumberFormatException
  1. to系列方法
  • toString方法

Integer類中西饵,toString方法有兩個蜈膨,其中一個是重寫了Object的toString方法悼沿, 另外兩個是靜態(tài)方法

#1 public String toString();

#2 public static String toString(int i);

#3 public static String toString(int i, int radix)

重寫的toString是調(diào)用了#2方法

#2 的實現(xiàn)

public static String toString(int i) {
    if (i == Integer.MIN_VALUE)
        return "-2147483648";
    // 通過stringSize的方法獲取傳入i的長度茸歧,如果是負(fù)數(shù)則多一位
    int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
    // 創(chuàng)建一個長度為size的字符數(shù)組
    char[] buf = new char[size];
    // 獲取i的字符形式給塞到buf中
    getChars(i, size, buf);
    return new String(buf, true);
}

static void getChars(int i, int index, char[] buf) {
    int q, r;
    int charPos = index;
    char sign = 0;
    // 如果i小于0則要轉(zhuǎn)換為整數(shù),記錄下轉(zhuǎn)換前的符號
    if (i < 0) {
        sign = '-';
        i = -i;
    }
    // 如果i大于或者等于65536需要显沈,獲取最后兩位來進(jìn)行處理
    while (i >= 65536) {
        q = i / 100;
        r = i - ((q << 6) + (q << 5) + (q << 2));
        i = q;
        // 各位
        buf [--charPos] = DigitOnes[r];
        // 十位
        buf [--charPos] = DigitTens[r];
    }
    // 死循環(huán)處理i软瞎,直到i為0退出循環(huán)
    for (;;) {
        // q、r兩個計算拉讯,是獲取i的最后一位涤浇,然后把獲取出來的數(shù)字獲取到預(yù)先定義的digits字符數(shù)組中的字符,并存入到buf中
        q = (i * 52429) >>> (16+3);
        r = i - ((q << 3) + (q << 1));
        buf [--charPos] = digits [r];
        i = q;
        if (i == 0) break;
    }
    // 如果不是0魔慷,則把上面的符號位加到上面去
    if (sign != 0) {
        buf [--charPos] = sign;
    }
}

#3 的實現(xiàn)

#3 提供了進(jìn)制轉(zhuǎn)換功能

public static String toString(int i, int radix) {
    // 如果進(jìn)制不在2到36進(jìn)制之類只锭,則默認(rèn)為10進(jìn)制
    if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
        radix = 10;
    // 如果是十進(jìn)制,直接調(diào)用toString方法返回
    if (radix == 10) {
        return toString(i);
    }
    
    char buf[] = new char[33];
    // 記錄符號位
    boolean negative = (i < 0);
    int charPos = 32;
    // 將正數(shù)變?yōu)樨?fù)數(shù)
    if (!negative) {
        i = -i;
    }

    while (i <= -radix) {
        // 取余
        buf[charPos--] = digits[-(i % radix)];
        i = i / radix;
    }
    // 將無需處理的丟到數(shù)組的最后
    buf[charPos] = digits[-i];
    // 還原符號位
    if (negative) {
        buf[--charPos] = '-';
    }

    return new String(buf, charPos, (33 - charPos));
}
  • toHexString院尔、toOctalString蜻展、toBinaryString

這些都是調(diào)用toUnsignedString0實現(xiàn)的(騷代碼喉誊,看不懂)

private static String toUnsignedString0(int val, int shift) {
    int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val);
    int chars = Math.max(((mag + (shift - 1)) / shift), 1);
    char[] buf = new char[chars];
    formatUnsignedInt(val, shift, buf, 0, chars);
    return new String(buf, true);
}
static int formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {
    int charPos = len;
    int radix = 1 << shift;
    int mask = radix - 1;
    do {
        buf[offset + --charPos] = Integer.digits[val & mask];
        val >>>= shift;
    } while (val != 0 && charPos > 0);
    return charPos;
}
public static int numberOfLeadingZeros(int i) {
    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;
}
  1. parse系列方法

它注釋里面給了一個警告,如果初始化時提早使用valueof纵顾,那么high可能為0

 public static int parseInt(String s, int radix)
                throws NumberFormatException{
    /*
        * WARNING: This method may be invoked early during VM initialization
        * before IntegerCache is initialized. Care must be taken to not use
        * the valueOf method.
        */

    if (s == null) {
        throw new NumberFormatException("null");
    }

    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;
    int i = 0, len = s.length();
    int limit = -Integer.MAX_VALUE;
    int multmin;
    int digit;

    if (len > 0) {
        // 取傳入s的第一個字符
        char firstChar = s.charAt(0);
        // 比較字符的ASCALL碼伍茄,+ 或者 - 的都比數(shù)字小
        if (firstChar < '0') {
            // 如果是負(fù)數(shù),負(fù)數(shù)標(biāo)記施逾,limit設(shè)置為最小值
            if (firstChar == '-') {
                negative = true;
                limit = Integer.MIN_VALUE;
            } else if (firstChar != '+')
                throw NumberFormatException.forInputString(s);

            if (len == 1) // Cannot have lone "+" or "-"
                throw NumberFormatException.forInputString(s);
            i++;
        }
        multmin = limit / radix;
        // i可以看做字符串的指針
        while (i < len) {
            // 將digit轉(zhuǎn)換為對應(yīng)的進(jìn)制數(shù)的數(shù)值
            digit = Character.digit(s.charAt(i++),radix);
            if (digit < 0) {
                throw NumberFormatException.forInputString(s);
            }
            if (result < multmin) {
                throw NumberFormatException.forInputString(s);
            }
            // 每循環(huán)一次都需要乘以進(jìn)制數(shù)敷矫,相當(dāng)于擴(kuò)大radix倍
            result *= radix;
            if (result < limit + digit) {
                throw NumberFormatException.forInputString(s);
            }
            // 因為防止溢出,所以結(jié)果集使用負(fù)數(shù)存儲
            result -= digit;
        }
    } else {
        throw NumberFormatException.forInputString(s);
    }
    return negative ? result : -result;
}

好像Integer常用的也就這些方法汉额,它其中很多方法是調(diào)用Long中的方法執(zhí)行的曹仗,或者是轉(zhuǎn)換成無符號的整數(shù)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蠕搜,隨后出現(xiàn)的幾起案子怎茫,更是在濱河造成了極大的恐慌,老刑警劉巖妓灌,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件轨蛤,死亡現(xiàn)場離奇詭異,居然都是意外死亡旬渠,警方通過查閱死者的電腦和手機(jī)俱萍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來告丢,“玉大人枪蘑,你說我怎么就攤上這事♂猓” “怎么了岳颇?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長颅湘。 經(jīng)常有香客問我话侧,道長,這世上最難降的妖魔是什么闯参? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任瞻鹏,我火速辦了婚禮,結(jié)果婚禮上鹿寨,老公的妹妹穿的比我還像新娘新博。我一直安慰自己,他們只是感情好脚草,可當(dāng)我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布赫悄。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪埂淮。 梳的紋絲不亂的頭發(fā)上姑隅,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天,我揣著相機(jī)與錄音倔撞,去河邊找鬼讲仰。 笑死,一個胖子當(dāng)著我的面吹牛误窖,可吹牛的內(nèi)容都是我干的叮盘。 我是一名探鬼主播秩贰,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼霹俺,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了毒费?” 一聲冷哼從身側(cè)響起丙唧,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎觅玻,沒想到半個月后想际,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡溪厘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年胡本,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片畸悬。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡侧甫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蹋宦,到底是詐尸還是另有隱情披粟,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布冷冗,位于F島的核電站守屉,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蒿辙。R本人自食惡果不足惜拇泛,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望思灌。 院中可真熱鬧俺叭,春花似錦、人聲如沸习瑰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至柠横,卻和暖如春窃款,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背牍氛。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工晨继, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人搬俊。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓紊扬,卻偏偏與公主長得像,于是被迫代替她去往敵國和親唉擂。 傳聞我的和親對象是個殘疾皇子餐屎,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)玩祟,斷路器腹缩,智...
    卡卡羅2017閱讀 134,665評論 18 139
  • Integer 本文源碼基于JDK8 Integer也是我們經(jīng)常使用的工具類、包裝類空扎,此文主要用于記錄學(xué)習(xí)筆記藏鹊,主...
    luoyoub閱讀 248評論 1 0
  • 2007年4月4日 23:15 精彩 極歡喜Lily送給我的和服, 寬袍長袖转锈,施施然盘寡,飄飄然, 她說撮慨, 買什么送給...
    SunnyLives閱讀 162評論 0 0
  • 作曲:陳大力,陳秀男 作詞:陳大力 演唱:王 杰 走過天涯路 終究還是回頭 看盡花似海 如雪落 難舍情和義 恩仇隨...
    loui14閱讀 241評論 0 0
  • 恩施竿痰,湖北省唯一一個少數(shù)民族自治州,世界硒都甫煞,土家文化底蘊(yùn)豐厚菇曲。 客車沿著盤山公路抵至海拔1398米的...
    張dela閱讀 162評論 0 1