作者:fbysss
msn:[email protected]
blog:blog.csdn.net/fbysss
声明:本文由fbysss原创,转载请注明出处
前言:
最近看到这样的说法:使用Integer.valueOf代替new Integer更有效率,原因是研究了Integer源码,发现有一个缓存可以利用。
对此我也一探究竟。发现这其实与Java的自动装箱拆箱有关,直接使用Integer i =数值的方式即可。
通过字节码研究是比较有效的方式。那我们来看看吧:
-------------------
Integer.valueOf源码:
-------------------
public static Integer valueOf(int i) {
final int offset = 128;
if (i >= -128 && i <= 127) { // must cache
return IntegerCache.cache[i + offset];
}
return new Integer(i);
}
-------------------
IntegerCache 源码(jdk1.6.0_12):
-------------------
private static class IntegerCache {
private IntegerCache(){}
static final Integer cache[] = new Integer[-(-128) + 127 + 1];//注意这个cache是final的
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Integer(i - 128);
}
源码1:
我们可以看到:
1.第3行(行标为3)调用了Integer.valueOf,一旦数字在缓存窗口中,则能够提高效率,那么我们可以认为,缓存不用白不用,的确比new Integer要好。
2..第8行(行标为8)进行了自动拆箱(intValue),目的是进行数字的加1运算
3.注意第13行,运算完毕之后,再次进行装箱(valueOf),这些运算都不影响cache本身,所以cache设计成只读即可,也不存在线程安全问题。------------------------
注意一点:
------------------------
最新版本的Jdk,Integer有改写,IntegerCache 的缓存窗口可以配置(通过JVM参数 -XX:AutoBoxCacheMax设置)。
/**
* 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. During VM initialization the
* getAndRemoveCacheProperties method may be used to get and remove any system
* properites that configure the cache size. At this time, the size of the
* cache may be controlled by the vm option -XX:AutoBoxCacheMax=<size>.
*/
// value of java.lang.Integer.IntegerCache.high property (obtained during VM init)
static void getAndRemoveCacheProperties() {
if (!sun.misc.VM.isBooted()) {
Properties props = System.getProperties();
integerCacheHighPropValue =
(String)props.remove("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null)
System.setProperties(props); // remove from system props
}
}
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() {}
}
本文编写时间仓促,若有描述不妥或论证有问题的地方,欢迎各位交流、指正。