成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

java.lang.Integer 源碼深入解讀

mingzhong / 1182人閱讀

摘要:最近算是比較深入的了解了一下的源碼,就想著寫點(diǎn)東西記錄一下,一來可以加深理解,再來也算是為我刷了那么久平臺貢獻(xiàn)一點(diǎn)自己的綿薄之力。這兩個(gè)方法都是給當(dāng)前的實(shí)例的屬性賦值,參數(shù)為類型的構(gòu)造器直接將參數(shù)賦值給屬性,參數(shù)為是將方法的返回值賦值。

最近算是比較深入的了解了一下Integer的源碼,就想著寫點(diǎn)東西記錄一下,一來可以加深理解,再來也算是為我刷了那么久segmentfault平臺貢獻(xiàn)一點(diǎn)自己的綿薄之力。

一、構(gòu)造函數(shù):
解讀一個(gè)類的源碼我喜歡從構(gòu)造函數(shù)入手,這里先上Integer的構(gòu)造源碼:

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

Integer類中提供了兩個(gè)構(gòu)造函數(shù),分別針對構(gòu)造參數(shù)為基本類型int和引用類型String。這兩個(gè)方法都是給當(dāng)前的實(shí)例的value屬性賦值,參數(shù)為int類型的構(gòu)造器直接將參數(shù)賦值給value屬性,參數(shù)為String是將parseInt(String s, int radix)方法的返回值賦值。JDK1.5之后,java提供了自動(dòng)裝箱和自動(dòng)拆箱的功能。自動(dòng)裝箱也就是調(diào)用了Integer類的一個(gè)靜態(tài)方法valueOf方法,先看源碼:

public static Integer valueOf(int i) {
    assert IntegerCache.high >= 127;
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

源碼中有一個(gè)IntegerCache,這一個(gè)私有的內(nèi)部類。這個(gè)類緩存了low - high之間數(shù)字的包裝類。關(guān)于這個(gè)類的分析在下面,反正你需要記住它把一些數(shù)字的包裝類提前緩存了,如果判斷成立就把緩存中的那個(gè)包裝類返回,如果不則new一個(gè)新的。這里也就明白了下面問題的原因了:

Integer a = 100;
Integer b = 100;

Integer c = 200;
Integer d = 200;
        
System.out.println(a == b);//true
System.out.println(c == d);//false

通過javap -c/javap -verbose 命令可以查看字節(jié)碼;紅色圈圈里就是我們jdk5之后的基本類型的自動(dòng)包裝的字節(jié)碼實(shí)現(xiàn),可以看出,此處是調(diào)用了Integer.valueOf(..)方法的:說白了就是Integer a = 100 等價(jià)于Integer a = Integer.valueOf(100)

二、IntegerCache:
先上源碼:

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) -1);
      }
      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() {}
  }

以上可以知道這個(gè)類是私有的且是靜態(tài)的,并且他有三個(gè)被final修飾的靜態(tài)filed外加一個(gè)靜態(tài)塊和一個(gè)私有的構(gòu)造器;很簡單很普通的一個(gè)類,被緩存的包裝類就介于low - high之間,low的值已經(jīng)寫死-128,而high的值由你的虛擬機(jī)決定sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"),既然是一個(gè)參數(shù)也就意味著你可以動(dòng)態(tài)設(shè)置,具體怎么設(shè)置自行百度。然后在循環(huán)中將low - high之間數(shù)字的裝箱后方法cache[]這個(gè)Integer類型的數(shù)組中。這樣就完成了緩存。

三、toString(int i): 照例先上源碼:

public static String toString(int i) {
    if (i == Integer.MIN_VALUE)
        return "-2147483648";
    int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
    char[] buf = new char[size];
    getChars(i, size, buf);
    return new String(buf, true);
}

這個(gè)方法內(nèi)部調(diào)用了兩個(gè)方法:stringSizegetChars,toString方法的實(shí)現(xiàn)也就是由這兩個(gè)方法合作完成,stringSize實(shí)現(xiàn)上很是比較簡單的,源碼我就不上了,它是用來計(jì)算參數(shù)i的位數(shù)也就是轉(zhuǎn)成字符串之后的字符串的長度。內(nèi)部結(jié)合一個(gè)已經(jīng)初始化好的int類型的數(shù)組sizeTable來完成這個(gè)計(jì)算。稍動(dòng)頭腦就能想明白,很巧妙的一個(gè)方法。然后來說說toString這個(gè)方法實(shí)現(xiàn)的最大功臣getChars這個(gè)方法,上源碼:

 static void getChars(int i, int index, char[] buf) {
    int q, r;
    int charPos = index;
    char sign = 0;

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

    // Generate two digits per iteration
    while (i >= 65536) {
        q = i / 100;
    // really: r = i - (q * 100);
        r = i - ((q << 6) + (q << 5) + (q << 2));
        i = q;
        buf [--charPos] = DigitOnes[r];
        buf [--charPos] = DigitTens[r];
    }

    // Fall thru to fast mode for smaller numbers
    // assert(i <= 65536, i);
    for (;;) {
        q = (i * 52429) >>> (16+3);
        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;
    }
}

三個(gè)參數(shù):i:被初始化的數(shù)字,index:這個(gè)數(shù)字的長度(包含了負(fù)數(shù)的符號“-”),buf:字符串的容器-一個(gè)char型數(shù)組。第一個(gè)if判斷,如果i<0,sign記下它的符號“-”,同時(shí)將i轉(zhuǎn)成整數(shù)。下面所有的操作也就只針對整數(shù)了,最后在判斷sign如果不等于零將sig你的值放在char數(shù)組的首位buf [--charPos] = sign;。 最后來分析方法中的兩個(gè)循環(huán):whilefor,其實(shí)這兩個(gè)循環(huán)做的事情一樣。只是while循環(huán)來處理i>65535的情況,且每次取兩位數(shù):

buf [--charPos] = DigitOnes[r];
buf [--charPos] = DigitTens[r];

剩下的情況由for循環(huán)處理,且每次去一個(gè)數(shù)字。至于為什么這么做:// Fall thru to fast mode for smaller numbers,這是官方注釋,意思就是真對小的數(shù)字使用快速方式。針對這塊的理解我也是參考了知乎上的網(wǎng)友的回答java源碼中Integer.class中有個(gè)getChars方法,里面有個(gè)52429是怎么確定的? 表示感謝。

至此Integer類的核心也就完了。就這吧!

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/66067.html

相關(guān)文章

  • 深入淺出了解“裝箱與拆箱”

    摘要:本章部分內(nèi)容從源碼中解讀一些自動(dòng)裝箱與拆箱的原理,以及會(huì)出現(xiàn)的一些陷阱已經(jīng)性能等。例題分析我們通過幾個(gè)經(jīng)典的問題,來看看大家到底理解了裝箱與拆箱的知識點(diǎn)沒。 showImg(https://img-blog.csdnimg.cn/20190426221838971.gif);showImg(https://img-blog.csdnimg.cn/20190426221918208.pn...

    FullStackDeveloper 評論0 收藏0
  • 為何Spring MVC可獲取到方法參數(shù)名,而MyBatis卻不行?【享學(xué)Spring MVC】

    每篇一句 胡適:多談些問題,少聊些主義 前言 Spring MVC和MyBatis作為當(dāng)下最為流行的兩個(gè)框架,大家平時(shí)開發(fā)中都在用。如果你往深了一步去思考,你應(yīng)該會(huì)有這樣的疑問: 在使用Spring MVC的時(shí)候,你即使不使用注解,只要參數(shù)名和請求參數(shù)的key對應(yīng)上了,就能自動(dòng)完成數(shù)值的封裝 在使用MyBatis(接口模式)時(shí),接口方法向xml里的SQL語句傳參時(shí),必須(當(dāng)然不是100%的必須,...

    孫淑建 評論0 收藏0
  • Java源碼閱讀筆記之Integer

    摘要:估計(jì)這就是推薦使用的主要原因吧正負(fù)標(biāo)識判斷輸入的字符串是否為開頭轉(zhuǎn)化邏輯字符串轉(zhuǎn)化為的關(guān)鍵在于數(shù)組,以進(jìn)制為例,用表示到,滿才會(huì)進(jìn)。 Integer的基本實(shí)現(xiàn)Integer的使用Integer封裝的操作 Integer的基本實(shí)現(xiàn) 基本描述:Integer是對原生基本類型int的封裝,其定義value來存儲值和一些用于描述int的信息 int value;//int int SIZE...

    wenzi 評論0 收藏0
  • 詳敘BeanWrapper和PropertyDescriptor

    摘要:關(guān)于它的數(shù)據(jù)轉(zhuǎn)換使用了如下兩種機(jī)制隸屬于規(guī)范。這種類中的方法主要用于訪問私有的字段,且方法名符合某種命名規(guī)則。如果在兩個(gè)模塊之間傳遞信息,可以將信息封裝進(jìn)中,這種對象稱為值對象,或。 每篇一句 千古以來要飯的沒有要早飯的,知道為什么嗎? 相關(guān)閱讀 【小家Spring】聊聊Spring中的數(shù)據(jù)轉(zhuǎn)換:Converter、ConversionService、TypeConverter、Pro...

    APICloud 評論0 收藏0
  • JVM執(zhí)行方法調(diào)用(一)- 重載與重寫

    摘要:重寫語言中的定義子類方法有一個(gè)方法與父類方法的名字相同且參數(shù)類型相同。父類方法的返回值可以替換掉子類方法的返回值。思維導(dǎo)圖參考文檔極客時(shí)間深入拆解虛擬機(jī)是如何執(zhí)行方法調(diào)用的上廣告 原文 回顧Java語言中的重載與重寫,并且看看JVM是怎么處理它們的。 重載Overload 定義: 在同一個(gè)類中有多個(gè)方法,它們的名字相同,但是參數(shù)類型不同。 或者,父子類中,子類有一個(gè)方法與父類非私有方...

    韓冰 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<