private static class IntegerCache { private IntegerCache(){}
static final Integer cache[] = new Integer[-(-128) + 127 + 1];
static { for(int i = 0; i < cache.length; i++) cache[i] = new Integer(i - 128); } }
/** * Returns a <tt>Integer</tt> instance representing the specified * <tt>int</tt> value. * If a new <tt>Integer</tt> instance is not required, this method * should generally be used in preference to the constructor * {@link #Integer(int)}, as this method is likely to yield * significantly better space and time performance by caching * frequently requested values. * * @param i an <code>int</code> value. * @return a <tt>Integer</tt> instance representing <tt>i</tt>. * @since 1.5 */ 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); }
此部分来自Integer源代码,Integer i = 1;这种自动封箱,等同于Integer i = Integer.valueOf(1);结合源代码来看,-128~127都被缓存起来,每次取出都是相同对象.而这个范围以外的都是new出来的,不同对象了.
private IntegerCache(){}
static final Integer cache[] = new Integer[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Integer(i - 128);
}
}
/**
* Returns a <tt>Integer</tt> instance representing the specified
* <tt>int</tt> value.
* If a new <tt>Integer</tt> instance is not required, this method
* should generally be used in preference to the constructor
* {@link #Integer(int)}, as this method is likely to yield
* significantly better space and time performance by caching
* frequently requested values.
*
* @param i an <code>int</code> value.
* @return a <tt>Integer</tt> instance representing <tt>i</tt>.
* @since 1.5
*/
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);
}
在client模式下该参数无效。这个参数是server模式专有的,在c2_globals.hpp中声明,默认值是128;不过这个默认值在默认条件下不起作用,要手动设置它的值或者是开启-XX:+AggressiveOpts参数才起作用。
很是不明白,为什么你说当i1=70 i2=70时:是相等的,这个大家很好理解,
但是当 i1=150 i2=150时:是不相等的。就不好理解了。对我来说,当 i1=150 i2=150时:是不相等的,这是理所当然。
而i1=70 i2=70时:是相等的,这才是奇怪的事!!!因为,你代码里,用的是 Integer,而不是 primitive type 的 int.只有 primitive type,用 == 比较才有意义。而对于类 Integer, 像任何 Object 的子类一样,它的值是要用 equals 函数来比较的。
如果用 == 来比较,比较的是参照的地址。只有在两个变量参照同一个类时,等于才成立。从Java语言角度讲,i1=70 i2=70时,没有任何保障,支持这两个 Integer, 应该相等。
如果它们相等,那时你中了大彩,运气好。那是编译器进行的某种优化行为。换一个环境,换一个编译器,它们就可能不相等 i1==i2.但是,i1.equals(i2) 永远成立,无论在什么执行环境。
总之,任何应用的 business logic 都不应该建立在 假设
“i1=70 i2=70时 i1==i2” 上。相反,而应该认为,这两个变数参照的是不同的 instance of Integer.
恩 你说的很对是缓存起来了,
但是我还有点不是很明白。
当第一次声明的时候 i1=70 在内存有一个i1的引用,
第二次声明i2的时候,这时候之前已经有了70这个内存地址和值了,怎么引用的,指针如何指向的,这块有点不明白。(如何利用缓存的),请大家在讨论一下!!!