<ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>


      int 是 Java 八大原始類型之一,是 Java 語(yǔ)言中為數(shù)不多不是對(duì)象的東西,Integer 是 int 的包裝類,里面使用了一個(gè) int
      類型的變量來(lái)存儲(chǔ)數(shù)據(jù),提供了一些整數(shù)之間的常用操作,常規(guī)性的介紹就這么一點(diǎn),程序員不喜歡說(shuō),程序員就喜歡源碼,我們還是來(lái)看源碼吧
      * @author Lee Boynton * @author Arthur van Hoff * @author Josh Bloch *
      @author Joseph D. Darcy * @since JDK1.0 */ public final class Integer extends
      Number implements Comparable<Integer> { /** * A constant holding the minimum
      value an {@code int} can * have, -2<sup>31</sup>. */ @Native public static
      final int MIN_VALUE = 0x80000000; /** * A constant holding the maximum value an
      {@code int} can * have, 2<sup>31</sup>-1. */ @Native public static final int
      MAX_VALUE = 0x7fffffff; /** * The value of the {@code Integer}. * * @serial */
      private final int value; /** * Constructs a newly allocated {@code Integer}
      object that * represents the specified {@code int} value. * * @param value the
      value to be represented by the * {@code Integer} object. */ public Integer(int
      value) { this.value = value; } /** * Constructs a newly allocated {@code
      Integer} object that * represents the {@code int} value indicated by the *
      {@code String} parameter. The string is converted to an * {@code int} value in
      exactly the manner used by the * {@code parseInt} method for radix 10. * *
      @param s the {@code String} to be converted to an * {@code Integer}. *
      @exception NumberFormatException if the {@code String} does not * contain a
      parsable integer. * @see java.lang.Integer#parseInt(java.lang.String, int) */
      public Integer(String s) throws NumberFormatException { this.value =
      parseInt(s, 10); }
      上面這段源碼是我截取出來(lái)的,在 Integer 類中,這些代碼不是連在一起的,把他們放在一起,那是因?yàn)槲蚁胝f(shuō)明點(diǎn)事情,我們仔細(xì)看看這段代碼,Integer
      類是被 final ,這說(shuō)明了什么?用于存放變量的 value 也被 private final 修飾,這又說(shuō)明了什么?看著這些是不是有點(diǎn)熟悉呢?
      沒錯(cuò),String 對(duì)象也是這樣的,這說(shuō)明 Integer 對(duì)象也是不可變的,所以以后如果被問(wèn)到 Integer 對(duì)象是不是不可變對(duì)象時(shí),記得回答是喔。為什么
      Integer 對(duì)象也會(huì)設(shè)計(jì)成不可變對(duì)象呢?其實(shí)我也不知道,我沒有從文檔中找到答案,但是在楊曉峰老師的文章中看到過(guò)有關(guān)說(shuō)明,楊曉峰老師說(shuō) Integer
      類設(shè)計(jì)成不可變跟 getInteger() 方法有關(guān)系,getInteger()方法的源碼如下:
      public static Integer getInteger(String nm, Integer val) { String v = null;
      try { v = System.getProperty(nm); } catch (IllegalArgumentException |
      NullPointerException e) { } if (v != null) { try { return Integer.decode(v); }
      catch (NumberFormatException e) { } } return val; }
      getInteger() 方法是用來(lái)獲取系統(tǒng)屬性的,我們通過(guò)屬性來(lái)設(shè)置服務(wù)器的某個(gè)服務(wù)器的端口,如果 Integer
      可變的話,那么我們就能夠輕易的改變這個(gè)屬性的值,這會(huì)使得我們的產(chǎn)品存在安全風(fēng)險(xiǎn)。

      上面我們我么簡(jiǎn)單的聊了一下 Integer 類的實(shí)現(xiàn),聊到 int 與 Integer,自然就少不了自動(dòng)裝箱和自動(dòng)拆箱。

      1、自動(dòng)裝箱、拆箱

      自動(dòng)裝箱和拆箱是從 JDK 1.5 開始引進(jìn)的功能,它是一種語(yǔ)法糖,Java 可以根據(jù)上下文,自動(dòng)的在原始類型和包裝類型中進(jìn)行轉(zhuǎn)換,簡(jiǎn)單的來(lái)說(shuō)就是 Java
      平臺(tái)保證了不同的寫法通過(guò)編譯之后會(huì)產(chǎn)生相同的字節(jié)碼,保證了運(yùn)行時(shí)是等價(jià)的。自動(dòng)裝箱和拆箱極大地簡(jiǎn)化了相關(guān)編程。

      自動(dòng)裝箱:將原始類型轉(zhuǎn)化為包裝類型的過(guò)程

      比如將 int 類型轉(zhuǎn)換成 integer
      類型,這就是原始類型到包裝類型的轉(zhuǎn)變,在編譯的時(shí)候,編譯器就會(huì)幫我們做自動(dòng)轉(zhuǎn)換,這個(gè)過(guò)程對(duì)我們程序員來(lái)說(shuō)是無(wú)感知的,例如這段給 Integer 對(duì)象賦值的代碼:
      Integer x = 3000;
      這段代碼經(jīng)過(guò)編譯器之后,會(huì)轉(zhuǎn)換成下面這段代碼:
      Integer x = Integer.valueOf(3000);
      這就是自動(dòng)裝箱過(guò)程,這個(gè)過(guò)程你是不知道的,所以它才叫自動(dòng)裝箱,在自動(dòng)裝箱的過(guò)程中使用到了 valueOf() 方法,來(lái)看看 JDK 中這個(gè)方法的源碼:
      public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <=
      IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return
      new Integer(i); }
      這個(gè)方法里,前面先進(jìn)行了一個(gè)緩存判斷,如果你不知道的話,先忽略掉它,最后返回了 new Integer(i) 對(duì)象引用,這個(gè)方法就是幫你去調(diào)用了
      Integer 類的構(gòu)造器。這就是自動(dòng)裝箱。

      自動(dòng)拆箱:將包裝類型轉(zhuǎn)換成原始類型的過(guò)程

      將 Integer 類型轉(zhuǎn)換為 Int
      類型,這是一個(gè)包裝類型轉(zhuǎn)成成原始類型的過(guò)程,在這個(gè)過(guò)程中就會(huì)涉及到自動(dòng)拆箱。來(lái)看看這段代碼(這是一段很操蛋的代碼,實(shí)際中應(yīng)該沒人這樣寫):
      Integer mm = 1000; int mmm = mm;
      在編譯的時(shí)候,這段代碼會(huì)被編譯器編譯成下面這段代碼:
      Integer mm = Integer.valueOf(1000); int mmm = mm.intValue();
      主要看int mmm = mm.intValue();這行代碼,這行代碼跟我們寫的不一樣了,使用到了一個(gè) intValue() 方法,來(lái)看看 Integer
      類中 intValue() 方法的源碼:
      /** * Returns the value of this {@code Integer} as an * {@code int}. */ public
      int intValue() { return value; }
      這個(gè)方法的作用就是把 Integer 對(duì)象中用來(lái)存儲(chǔ)值的 value
      變量返回了,這就是自動(dòng)拆箱,好了,關(guān)于自動(dòng)裝箱和自動(dòng)拆箱我們都了解了,還記得自動(dòng)裝箱過(guò)程中涉及到的緩存嗎?接下來(lái)我們一起了解一下。

      2、Integer 緩存策略

      在自動(dòng)裝箱的 valueOf() 方法中,我們看到了有一個(gè)緩存判斷的操作,是的,Integer
      類中有緩存池,會(huì)將使用頻繁的值緩存起來(lái),以便提高系統(tǒng)的使用性能,在自動(dòng)裝箱的過(guò)程中,會(huì)先判斷該值是否存在緩存池中,如果存在直接從緩存池中取出引用返回,如果不存在則調(diào)用構(gòu)造函數(shù)構(gòu)造對(duì)象。緩存是自動(dòng)裝箱操作獨(dú)享的,直接通過(guò)構(gòu)造函數(shù)構(gòu)造出來(lái)的
      Integer 對(duì)象即使值在緩存范圍內(nèi),也不會(huì)使用到緩存池。在 Integer 類中,使用了一個(gè)內(nèi)部類來(lái)實(shí)現(xiàn)緩存,這個(gè)內(nèi)部類叫做
      IntegerCache,IntegerCache 類的源代碼如下:
      /** * Cache to support the object identity semantics of autoboxing for values
      between * -128 and 127 (inclusive) as required by JLS. * * The cache is
      initialized on first usage. The size of the cache * may be controlled by the
      {@code -XX:AutoBoxCacheMax=<size>} option. * During VM initialization,
      java.lang.Integer.IntegerCache.high property * may be set and saved in the
      private system properties in the * sun.misc.VM class. */ 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) { try { 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); }
      catch( NumberFormatException nfe) { // If the property cannot be parsed into an
      int, ignore it. } } high = h; cache = new Integer[(high - low) + 1]; int j =
      low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); //
      range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >=
      127; } private IntegerCache() {} }
      從源碼和 Java 注釋中我們可以看出 IntegerCache 的緩存默認(rèn)值范圍 -128 ~ 127 。但是我們也可以在啟動(dòng)時(shí)通過(guò) JVM
      命令來(lái)設(shè)置緩存范圍的最大值,只需要在啟動(dòng)時(shí)添加 -XX:AutoBoxCacheMax=
      參數(shù)就可以了,但是記得這個(gè) size 可不要亂設(shè)置,需要全方位考慮,比如你設(shè)置成 10 萬(wàn),那么這 10
      萬(wàn)個(gè)數(shù)都會(huì)在啟動(dòng)剛啟動(dòng)時(shí)就添加到內(nèi)存中,想想這會(huì)占用你多少內(nèi)存?這樣做就得不償失了,Java 公司設(shè)置成 -128 ~ 127
      是有道理的,發(fā)現(xiàn)大部分人使用的值都在 -128 ~ 127 之間,這些值占用的內(nèi)存比較少,性能上比通過(guò)構(gòu)造函數(shù)構(gòu)造對(duì)象要好不少。如何你使用的 Integer
      的值在緩存范圍的話,就用 Integer i = value 的形式構(gòu)建對(duì)象,如果你的值不在緩存范圍內(nèi),則使用 Integer i = new
      Integer(value) 的形式構(gòu)建 Integer 對(duì)象,避免自動(dòng)裝箱的過(guò)程。最后我們來(lái)看一下 Integer 對(duì)象比較常用的方法 parseInt 方法

      3、parseInt() 方法

      parseInt() 方法的作用是用來(lái)將整數(shù)型的字符串轉(zhuǎn)換成整數(shù),parseInt 方法需要和 valueOf
      方法區(qū)分開來(lái),有不少人會(huì)問(wèn)這兩方法有什么區(qū)別,最后度會(huì)返回 int 類型,都能將整數(shù)型的字符串轉(zhuǎn)換成整數(shù)型,比如這段代碼
      System.out.println(Integer.parseInt("+12"));
      System.out.println(Integer.valueOf("+12"));
      最后都會(huì)輸出 12 ,輸出的結(jié)果相同是因?yàn)?valueOf 方法使用中會(huì)調(diào)用 parseInt 方法將整數(shù)型字符轉(zhuǎn)換為整數(shù),并且會(huì)在內(nèi)存中創(chuàng)建一個(gè)值為 12
      的 Integer 對(duì)象,然后返回這個(gè)對(duì)象引用。而 parseInt
      方法只會(huì)幫你將整數(shù)型字符轉(zhuǎn)換為整數(shù),不會(huì)額外的創(chuàng)建對(duì)象。所以它們兩得到相同的結(jié)果純屬是巧合。一起瞅瞅 parseInt 源代碼:
      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) { 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) // Cannot have lone "+"
      or "-" throw NumberFormatException.forInputString(s); i++; } multmin = limit /
      radix; while (i < len) { // Accumulating negatively avoids surprises near
      MAX_VALUE 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 { throw NumberFormatException.forInputString(s); } return negative ?
      result : -result; }
      在調(diào)用 parseInt 方法時(shí),我們可以傳入一個(gè) radix 變量,用來(lái)告訴它使用什么進(jìn)制來(lái)進(jìn)行轉(zhuǎn)換,默認(rèn)使用的是十進(jìn)制。

      文章不足之處,望大家多多指點(diǎn),共同學(xué)習(xí),共同進(jìn)步

      最后

      打個(gè)小廣告,歡迎掃碼關(guān)注微信公眾號(hào):「平頭哥的技術(shù)博文」,一起進(jìn)步吧。

      友情鏈接
      ioDraw流程圖
      API參考文檔
      OK工具箱
      云服務(wù)器優(yōu)惠
      阿里云優(yōu)惠券
      騰訊云優(yōu)惠券
      京東云優(yōu)惠券
      站點(diǎn)信息
      問(wèn)題反饋
      郵箱:[email protected]
      QQ群:637538335
      關(guān)注微信

        <ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>
          欧美超级操逼视频免费观看 | 娇妻被邻居脔到高潮呻吟小说 | 午夜一区在线 | 女同做爱成人网站 | 骚片在线观看 | 办公室高h荡肉呻吟在线观看 | 2025天天操 | 亚洲欧洲另类小说 | 亚洲第一毛片 | 一级a免一级a做免费线看内裤英文 |