Integer i1 = 150;
Integer i2 = 150;
if(i1==i2){
System.out.println("====相等");
}else{
System.out.println("====不相等");
}这个例子中有这样一个现象:
当i1=70 i2=70时:是相等的,这个大家很好理解,
但是当 i1=150 i2=150时:是不相等的。
请大牛给予详细的解释。
不要“Integer的数据范围”一句带过 
Integer 对象的比较

解决方案 »

  1.   

    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);  
       }  
      

  2.   

    此部分来自Integer源代码,Integer i = 1;这种自动封箱,等同于Integer i = Integer.valueOf(1);结合源代码来看,-128~127都被缓存起来,每次取出都是相同对象.而这个范围以外的都是new出来的,不同对象了.
      

  3.   

    http://www.ticmy.com/?p=110
      

  4.   

    使用Oracle/Sun JDK 6,在server模式下,使用-XX:AutoBoxCacheMax=NNN参数即可将Integer的自动缓存区间设置为[-128,NNN]。注意区间的下界固定在-128不可配置。
    在client模式下该参数无效。这个参数是server模式专有的,在c2_globals.hpp中声明,默认值是128;不过这个默认值在默认条件下不起作用,要手动设置它的值或者是开启-XX:+AggressiveOpts参数才起作用。
      

  5.   


    很是不明白,为什么你说当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.
      

  6.   


    恩 你说的很对是缓存起来了,
    但是我还有点不是很明白。
    当第一次声明的时候 i1=70 在内存有一个i1的引用,
    第二次声明i2的时候,这时候之前已经有了70这个内存地址和值了,怎么引用的,指针如何指向的,这块有点不明白。(如何利用缓存的),请大家在讨论一下!!!