8大基本類型的包裝類型緩存探究

目錄

自身範圍緩存

boolean

boolean 的包裝類型,緩存最簡單,直接定義爲靜態常量就可以

public final class Boolean implements java.io.Serializable,
                                      Comparable<Boolean>
{
    public static final Boolean TRUE = new Boolean(true);

    public static final Boolean FALSE = new Boolean(false);

    public static Boolean valueOf(boolean b) {
        return (b ? TRUE : FALSE);
    }
}

char

ascii 碼範圍爲 0-127, 這裏只緩存ascii碼範圍的char
Character 靜態內部類 CharacterCache

不過通過下面這段代碼可以看出來,他的範圍是: 0<=x<=127

public final
class Character implements java.io.Serializable, Comparable<Character> {

    public static Character valueOf(char c) {
        if (c <= 127) { // must cache
            return CharacterCache.cache[(int)c];
        }
        return new Character(c);
    }

    private static class CharacterCache {
        private CharacterCache(){}

        static final Character cache[] = new Character[127 + 1];

        static {
            for (int i = 0; i < cache.length; i++)
                cache[i] = new Character((char)i);
        }
    }
}

byte

byte 的範圍是: -128<=x<=127

所以byte 一定是從緩存裏面獲取

-(-128) + 127 + 1 這一段的意思就是說 (-128~-1)+(1~127)+0 一共256個數

public final class Byte extends Number implements Comparable<Byte> {
  public static Byte valueOf(byte b) {
        final int offset = 128;
        return ByteCache.cache[(int)b + offset];
  }

  private static class ByteCache {
      private ByteCache(){}

      static final Byte cache[] = new Byte[-(-128) + 127 + 1];

      static {
          for(int i = 0; i < cache.length; i++)
              cache[i] = new Byte((byte)(i - 128));
      }
  }
}

範圍爲256的緩存

short

和byte 範圍一樣, 但是如果超過了 -128<=x<=127 這個範圍,就不會從緩存中獲取了

public final class Short extends Number implements Comparable<Short> {
    public static Short valueOf(short s) {
        final int offset = 128;
        int sAsInt = s;
        if (sAsInt >= -128 && sAsInt <= 127) { // must cache
            return ShortCache.cache[sAsInt + offset];
        }
        return new Short(s);
    }

    private static class ShortCache {
        private ShortCache(){}

        static final Short cache[] = new Short[-(-128) + 127 + 1];

        static {
            for(int i = 0; i < cache.length; i++)
                cache[i] = new Short((short)(i - 128));
        }
    }
}

int (可以通過參數配置上限)

這裏的從緩存中獲取的代碼是一樣的,重點是 IntegerCache 的範圍是可以配置的

從源碼中可以看出來 最低值一定是-128 是不可以修改的,但是上限值high 是可以修改的。

通過jvm參數: -Djava.lang.Integer.IntegerCache.high=1024 修改爲1024

  1. 判斷是否有jvm參數java.lang.Integer.IntegerCache.high
  2. 解析爲 int 類型(解析失敗就用默認值127)
  3. 修改最大值和最小值
    • 如果小於127 那麼 high = 127
    • 如果 大於 Integer.MAX_VALUE - 129 ,就設置爲 Integer.MAX_VALUE - 129
  4. 將 low<=x<=high的值加入到緩存
  5. 驗證 IntegerCache.high > 127
public final class Integer extends Number implements Comparable<Integer> {
    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

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

這裏的 IntegerCache 無法斷點,因爲在進入main方法之前,就已經被其他的類加載了.

long

範圍: -128<=x<=127

public final class Long extends Number implements Comparable<Long> {
    public static Long valueOf(long l) {
        final int offset = 128;
        if (l >= -128 && l <= 127) { // will cache
            return LongCache.cache[(int)l + offset];
        }
        return new Long(l);
    }

    private static class LongCache {
            private LongCache(){}

            static final Long cache[] = new Long[-(-128) + 127 + 1];

            static {
                for(int i = 0; i < cache.length; i++)
                    cache[i] = new Long(i - 128);
            }
     }
}

不被緩存

valueOf 時, 直接new 包裝類型的對象,然後返回

float

public final class Float extends Number implements Comparable<Float> {
  public static Float valueOf(float f) {
        return new Float(f); 
  }
}

double

public final class Double extends Number implements Comparable<Double> {
    public static Double valueOf(double d) {
        return new Double(d);
    }
}
發佈了52 篇原創文章 · 獲贊 26 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章