Integer源碼分析——下(jdk11)

Integer與原生類型轉換

Integer提供了幾個與原生類型轉換的方法:

 public int intValue() {
        return value;
  }

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

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

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

由上面的源碼可知,Integer類型轉換原生類型喘先,只需要把value進行對應類型的強制轉換即可,因為Integer中實際存儲的值存儲在value變量中廷粒。

Integer.getInteger(String nm)

getInteger是Integer的靜態(tài)方法窘拯,參數(shù)nm是系統(tǒng)變量key,即從系統(tǒng)變量nm讀取字符串坝茎,然后再轉換為對應的Integer涤姊,此方法有3個重載方法:

public static Integer getInteger(String nm) 
public static Integer getInteger(String nm, int val)
public static Integer getInteger(String nm, Integer val) 

這三個方法中,后面兩個方法提供了一個默認值嗤放,當nm的系統(tǒng)變量為null思喊,返回方法傳入的默認值val

下面重點分析getInteger(String nm, Integer val)的實現(xiàn)邏輯,因為其他兩個方法的實現(xiàn),都是通過調(diào)用此方法來實現(xiàn)的:

 public static Integer getInteger(String nm, Integer val) {
        String v = null;
        //獲取系統(tǒng)變量nm的值
        try {
            v = System.getProperty(nm);
        } catch (IllegalArgumentException | NullPointerException e) {
        }
        //當v不為null的時候次酌,調(diào)用Integer.decode(v)方法
        if (v != null) {
            try {
                return Integer.decode(v);
            } catch (NumberFormatException e) {
            }
        }
        //如果v==null恨课,返回默認值
        return val;
}

程序中使用System.getProperty(nm);獲取的系統(tǒng)變量舆乔,通常是程序,用戶剂公,jvm等相關信息希俩,如果用戶想要設置自定義的系統(tǒng)變量,通掣倭桑可以在啟動程序的時候颜武,使用下面的方法:java -jar JarName -DpropertyName=value
propertyName就是用戶設置的系統(tǒng)變量的key

下面介紹一下Integer.decode(v)的實現(xiàn)原理

public static Integer decode(String nm) throws NumberFormatException {
        //表示進制 8, 10拖吼,16鳞上,默認是10
        int radix = 10;
        //字符串的當前位置
        int index = 0;
        boolean negative = false;
        Integer result;

        if (nm.length() == 0)
            throw new NumberFormatException("Zero length string");
        //獲取nm的第一個字符,然后判斷是正數(shù)還是負數(shù)
        char firstChar = nm.charAt(0);
        if (firstChar == '-') {
            negative = true;
            index++;
        } else if (firstChar == '+')
            index++;

        //然后獲取除了符號位之后的數(shù)字字符串的開頭幾個字符吊档,
        //來判斷數(shù)字的進制形式
        if (nm.startsWith("0x", index) || nm.startsWith("0X", index)) {
            index += 2;
            radix = 16;
        }
        else if (nm.startsWith("#", index)) {
            index ++;
            radix = 16;
        }
        else if (nm.startsWith("0", index) && nm.length() > 1 + index) {
            index ++;
            radix = 8;
        }
        
        if (nm.startsWith("-", index) || nm.startsWith("+", index))
            throw new NumberFormatException("Sign character in wrong position");
        //對字符串經(jīng)過上面步驟的校驗因块,獲取nm代表字符串的進制和數(shù)字字符串,
        //通過調(diào)用Integer.valueOf對nm進行真正的字符到數(shù)字的轉換籍铁,
        //Integer.valueOf具體實現(xiàn)原理參考:[Integer源碼分析——上 (jdk11)]
        try {
            result = Integer.valueOf(nm.substring(index), radix);
            result = negative ? Integer.valueOf(-result.intValue()) : result;
        } catch (NumberFormatException e) {
            String constant = negative ? ("-" + nm.substring(index))
                                       : nm.substring(index);
            result = Integer.valueOf(constant, radix);
        }
        return result;
}

Integer源碼分析——上 (jdk11)

注意這里進行了兩步轉換:


result = Integer.valueOf(nm.substring(index), radix);
result = negative ? Integer.valueOf(-result.intValue()) : result;
 

由于nm.substring(index)是去掉了正負符號和進制類型涡上,因此第一次調(diào)用valueOf得到的是正數(shù)。如果nm表示的負數(shù)拒名,然后需要第二步進行一個正負轉換吩愧。

這里注意的是當拋出NumberFormatException異常是,會執(zhí)行下面兩行代碼:

String constant = negative ? ("-" + nm.substring(index))
                                       : nm.substring(index);
result = Integer.valueOf(constant, radix);

這里的原理呢增显?
當nm="-2147483648"雁佳,在執(zhí)行Integer.valueOf(nm.substring(index), radix)的時候,nm.substring(index)的結果是"2147483648",由于int類型值得范圍是:

-2147483648<=int<=2147483647

而因此在執(zhí)行Integer.valueOf("2147483648", 10)同云,會拋出異常NumberFormatException糖权,因為"2147483648"在轉換的時候出現(xiàn)了溢出,因此需要通過String constant = negative ? ("-" + "2147483648") : "2147483648"; 把"2147483648"轉換為"-2147483648"炸站,然后再調(diào)用Integer.valueOf("-2147483648", radix);
這樣的處理方法可以正確的解決"-2147483648"轉為int的溢出問題星澳。

Integer常用的方法的實現(xiàn)原理就分析到這里,謝謝旱易!

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末禁偎,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子阀坏,更是在濱河造成了極大的恐慌如暖,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件忌堂,死亡現(xiàn)場離奇詭異盒至,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門枷遂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來寝蹈,“玉大人,你說我怎么就攤上這事登淘。” “怎么了封字?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵黔州,是天一觀的道長。 經(jīng)常有香客問我阔籽,道長流妻,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任笆制,我火速辦了婚禮绅这,結果婚禮上,老公的妹妹穿的比我還像新娘在辆。我一直安慰自己证薇,他們只是感情好,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布匆篓。 她就那樣靜靜地躺著浑度,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鸦概。 梳的紋絲不亂的頭發(fā)上箩张,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機與錄音窗市,去河邊找鬼先慷。 笑死,一個胖子當著我的面吹牛咨察,可吹牛的內(nèi)容都是我干的论熙。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼摄狱,長吁一口氣:“原來是場噩夢啊……” “哼赴肚!你這毒婦竟也來了?” 一聲冷哼從身側響起二蓝,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤誉券,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后刊愚,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體踊跟,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了商玫。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片箕憾。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖拳昌,靈堂內(nèi)的尸體忽然破棺而出袭异,到底是詐尸還是另有隱情,我是刑警寧澤炬藤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布御铃,位于F島的核電站,受9級特大地震影響沈矿,放射性物質(zhì)發(fā)生泄漏上真。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一羹膳、第九天 我趴在偏房一處隱蔽的房頂上張望睡互。 院中可真熱鬧,春花似錦陵像、人聲如沸就珠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嗓违。三九已至,卻和暖如春图贸,著一層夾襖步出監(jiān)牢的瞬間蹂季,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工疏日, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留偿洁,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓沟优,卻偏偏與公主長得像涕滋,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子挠阁,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

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