在网上看到的,希望对在这方面有欠缺的同学有帮助
关于java基本数据类型的包装类的自动装箱池的大小
一直以为Integer的自动装箱池的大小是-128~127,今天看了jdk1.6的源代码,发现其实并不一定的。大家都知道java有8种基本类型,它们都有自己的包装类。而Byte,Character,Short,Integer,Long都有一个自动装箱池,我一开始以为除了Character的自动装箱池的大小为0~127以外,其他都是-128~127。但是我在看jdk源代码的时候发现Integer的自动装箱池的实现跟其他几个包装类并不一样,我们先来看看Integer类好Short两个包装类的实现。- Integer类的自动装箱池的实现:
- private static class IntegerCache {
- static final int high;
- static final Integer cache[];
- static {
- final int low = -128;
- // high value may be configured by property
- int h = 127;
- if (integerCacheHighPropValue != null) {
- // Use Long.decode here to avoid invoking methods that
- // require Integer's autoboxing cache to be initialized
- int i = Long.decode(integerCacheHighPropValue).intValue();
- i = Math.max(i, 127);
- // Maximum array size is Integer.MAX_VALUE
- h = Math.min(i, Integer.MAX_VALUE - -low);
- }
- 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() {}
- }
- <p>Short和其他包装类(Character除外,不过原理一样,只是范围不一样)的自动装箱池的实现:</p>
- <div class="cnblogs_code"><pre><span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">static</span> <span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> ShortCache {
- </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> ShortCache(){}
- </span><span style="color: rgb(0, 0, 255);">static</span> <span style="color: rgb(0, 0, 255);">final</span> Short cache[] = <span style="color: rgb(0, 0, 255);">new</span> Short[-(-128) + 127 + 1<span style="color: rgb(0, 0, 0);">];
- </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> {
- </span><span style="color: rgb(0, 0, 255);">for</span>(<span style="color: rgb(0, 0, 255);">int</span> i = 0; i < cache.length; i++<span style="color: rgb(0, 0, 0);">)
- cache[i] </span>= <span style="color: rgb(0, 0, 255);">new</span> Short((<span style="color: rgb(0, 0, 255);">short</span>)(i - 128<span style="color: rgb(0, 0, 0);">));
- }
- }</span></pre></div>
- <p>经过比较我们发现,Integer的自动装箱池的最大值并不是一直是127的,当integerCacheHighPropValue不为空的时候,最大值是由integerCacheHighPropValue决定的。我们来看看integerCacheHighPropValue的是在哪儿被赋值的:</p>
- <div class="cnblogs_code"><pre><span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> String integerCacheHighPropValue;
- </span><span style="color: rgb(0, 0, 255);">static</span> <span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> getAndRemoveCacheProperties() {
- </span><span style="color: rgb(0, 0, 255);">if</span> (!<span style="color: rgb(0, 0, 0);">sun.misc.VM.isBooted()) {
- Properties props </span>=<span style="color: rgb(0, 0, 0);"> System.getProperties();
- integerCacheHighPropValue </span>=<span style="color: rgb(0, 0, 0);">
- (String)props.remove(</span>"java.lang.Integer.IntegerCache.high"<span style="color: rgb(0, 0, 0);">);
- </span><span style="color: rgb(0, 0, 255);">if</span> (integerCacheHighPropValue != <span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">)
- System.setProperties(props); </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> remove from system props</span>
- <span style="color: rgb(0, 0, 0);"> }
- }</span></pre></div>
- <p>这段代码告诉我们,integerCacheHighPropValue是通过读取系统配置获得的,也就是说Integer的自动装箱池的大小是可以配置的。我们来看看</p>
- <p>getAndRemoveCacheProperties方法的注释就一目了然了。<img alt="" src="http://pic002.cnblogs.com/images/2012/160039/2012071512430459.png"></p>
- <p>我们可以在虚拟机参数里面配置Integer的自动装箱池的大小。我们来验证一下。</p>
- <p>默认配置时,<img alt="" src="http://images.cnblogs.com/cnblogs_com/itnote/396086/r_QQ%e6%88%aa%e5%9b%be20120715124904.png" width="539" height="114"></p>
- <p><img alt="" src="http://images.cnblogs.com/cnblogs_com/itnote/396086/r_QQ%e6%88%aa%e5%9b%be20120715125351.png" width="338" height="333"> </p>
- <p> 结果:<img alt="" src="http://images.cnblogs.com/cnblogs_com/itnote/396086/r_QQ%e6%88%aa%e5%9b%be20120715125551.png" width="205" height="87"></p>
- <p>修改虚拟机参数:<img alt="" src="http://images.cnblogs.com/cnblogs_com/itnote/396086/r_QQ%e6%88%aa%e5%9b%be20120715125722.png" width="436" height="84"></p>
- <p>结果:<img alt="" src="http://images.cnblogs.com/cnblogs_com/itnote/396086/r_QQ%e6%88%aa%e5%9b%be20120715125852.png" width="184" height="88"></p>
- <p>我们修改Integer的自动装箱池的大小为256。所以第二个输出的结果为true。由于第四个输出仍为false,所以我们还可以推断:修改虚拟机的AutoBoxCacheMax的大小只会影响Integer,而不会影响其他包装类。为什么其他包装类不跟Integer一样设计成可配置的呢?这就不得而知了。</p>
复制代码 |