这种问题有点钻牛角尖,但相信想把JAVA学好学透的人都会喜欢。public class Test {
public static void main(String[] args) {
Integer i1 = 100;
Integer i2 = 100;
if (i1 == i2) {
System.out.println("i1==i2");
} else {
System.out.println("i1!=i2");
} Integer i3 = 200;
Integer i4 = 200;
if (i3 == i4) {
System.out.println("i3==i4");
} else {
System.out.println("i3!=i4");
}
}
}结果:
i1==i2
i3!=i4这是为什么?
答案为白色,选中查看:
在用Integer比较的时候是会分两种情况的,当取值在-128~127之间时,是用原生数据类型,也就是int去作比较,除此之外都是用Integer,也就是比较它们的地址,所以才得出了以上的结果!

解决方案 »

  1.   

    呵呵,确实如此,估计是JVM编译器的问题
      

  2.   

    package com.test;
    public class 解包装包 {
       public static void main(String []args) {
         Integer a = 100;
         Integer b = 100;
         System.out.println(a==b);
       }
    }
    打印结果为:true
    但是如果换成 128 > var >= -128 之外的整数就打false了。
    这是什么原因呢?
    1。java在编译的时候 Integer a = 100; 被翻译成-> Integer a = Integer.valueOf(100);
    2。比较的时候仍然是对象的比较
    3。在jdk源码中

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




    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 = new Integer(i - 128); 



    这边是java为了提高效率,初始化了-128--127之间的整数对象
    所以在赋值在这个范围内都是同一个对象。
    再加一句
    Integer a = 100;
    a++;
    //这边a++是新创建了一个对象,不是以前的对象。
        public static void main(String []args) {
            Integer a = 100;
            Integer b = a;
            a++;
            System.out.println(a==b);
        }
    打印就是false
    对于127--128没有多大关系,但是在这范围之外就影响性能了吧,就像StringBuffer VS String一样了看了这么一篇文章JAVA为什么要这样做呢?真是学到了
      

  3.   

    找到原因了,不能用==,用下面的就可以处理了
     Integer i1 = 100;
            Integer i2 = 100;
            if (i1.equals(i2)) {
                System.out.println("i1==i2");
            } else {
                System.out.println("i1!=i2");
            }        Integer i3 = 200;
            Integer i4 = 200;
            System.out.println(i3);
            System.out.println(i4);
            if (i3.equals(i4)) {
                System.out.println("i3==i4");
            } else {
                System.out.println("i3!=i4");
            }
      

  4.   

    哦是为了效率才想起来,java “==”就是比较引用,没有重载过而由于-128至127内的Interger都是同一个对象引用,所以第一个比较式true之外的Interger 则不是同一个对象,所以比较为false重载的应该是equals()方法,所以如果用equals来比较应该都为true学到了
      

  5.   

    有意思,应该涉及jvm优化问题吧,但好像数字不是很大,没必要优化啊。期待高手解答
      

  6.   

    这个问题讨论的次数虽然没有 String 问题这么多,但是至少也有 10 次了。
      

  7.   

    http://topic.csdn.net/u/20090519/18/7b8cf7ef-bc06-4d26-8a2c-692eb0562231.html
    我这个帖子的最后有说明
      

  8.   

    呵呵 有见地 居然没注意到这些问题 以为Integer 就是新建 int 就是引用  收获了 ^_^
      

  9.   


    这个问题的确讨论很多次了。 这里再复习一次。
    因为在JDK源码中Integer类有一个内部类IntegerCache,它默认创建了一个-128~127的Integer对象数组。
    只要比较的是在这256个数内,就直接在对象池里查找并返回该对象。
    这是Java处于性能的考虑,目的是节省内存。
    至于范围之外的,不同的引用当然不相等了。
      

  10.   

    使用了Facade模式,但弄出太多对象来又不太合适,所以取个常用的范围预先存起来了,
    但不知道java为什么不像处理String那样,每创建出一个对象,就放到池里公用。也许sun经过统计发现字符串重用的可能性高,而整数重用的概率比较低吧。
      

  11.   

    很简单,就是范围的问题,-128~127,就是TRUE,其他的FALSE
    因为SUN在设计这个INTEGER包装类的时候,考虑了效率问题,查看INTEGER类源代码就很明白了。
      

  12.   

    此题已经讨论过了,是Java自动装箱操作。(楼主百度!)和String完全不是一码事儿!!!
      

  13.   

    看这段代码,你就明白了,当一个int或者Integer型数在[-128,127]之间时,是做过特殊处理的: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);
        }
      

  14.   

    呵呵,与java基础教程的运算部分题目类似。==与equals()
      

  15.   

    其实就是==于equal(),基本类型与引用类型的用法区别!
        Integer是一个包装类,属于引用类型比较的时候是用引用对象比较而不是内存值!所以用==是出发点错误了
    而错误得到的结果不同是因为在Integer类中-128~128之间的数值都是已经初始化了的,以便给对象赋-128-128之间的值时,系统不要重新给这个对象开内存空间,目的在提高效率!
      

  16.   

    貌似只有在jdk5.0以上才会有你这样的结果
      

  17.   

    jdk1.5新特性!范围的问题!!!!!!!!!
      

  18.   

    -128至127内的Interger使用同一内存空间
      

  19.   

    你用equals这个一定是一样的,因为重写了equals方法
      

  20.   

    这个以前讨论过,借用一个评论:当这个值在-128和127之间时,会用缓存保存起来,供多次使用,以节约内存。 
    如果不在这个范围内,则创建一个新的Integer对象。
      

  21.   

    sun的编译器是这样处理的: 
    Integer i=Integer.valueOf(3); 
    而不是通过new来创建了,因为Integer类中静态的创建了-128~+127之间的对象,需要的数在这个范围之内时,直接返回,此范围之外的数才通过new来创建. 
    简单测试. 
    Integer i=3; 
    Integer j=3; 
    我们测试i==j会发现它是true. 
    Integer i=129; 
    Integer j=129; 
    我们测试i==j会发现它是false. 
      

  22.   

      这是因为integer对象池只保存从-128-127之间的整数,也就是说在这个范围的整数如果直接赋值给一个integer对象是在对象池中取,但超出这个范围即使直接赋给integer一个对象,也会生成新对象.就象200>127一样是新生成的对象,而100是从对象池中取出的当然为true.
      

  23.   

    看下Integer 的源码就什么都明白了.
      

  24.   

    小例子展现出Java内部设计模式的问题。
      

  25.   

    你比较的是不是值,而是对象你要是这样比的话就可以了public class Zalian {
     public static void main(String[] args) {
            Integer i1 = 100;
            Integer i2 = 100;
            if (i1.equals(i2)) {
                System.out.println("i1==i2");
            } else {
                System.out.println("i1!=i2");
            }         Integer i3 = 150;
            Integer i4 = 150;
            if (i3.equals(i4)) {
                System.out.println("i3==i4");
            } else {
                System.out.println("i3!=i4");
            }
        }}
      

  26.   

    第一种:
    public class Test {
        public static void main(String[] args) {
            Integer i1 = 100;
            Integer i2 = 100;
            if (i1 == i2) {
                System.out.println("i1==i2");
            } else {
                System.out.println("i1!=i2");
            }        Integer i3 = 128;
            Integer i4 = 128;
            if (i3 == i4) {
                System.out.println("i3==i4");
            } else {
                System.out.println("i3!=i4");
            }
         
          }
    }输出是:
    i1==i2
    i3!=i4
    第二种:public class Test {
        public static void main(String[] args) {
            Integer i1 = 100;
            Integer i2 = 100;
            if (i1 == i2) {
                System.out.println("i1==i2");
            } else {
                System.out.println("i1!=i2");
            }        Integer i3 = 127;
            Integer i4 = 127;
            if (i3 == i4) {
                System.out.println("i3==i4");
            } else {
                System.out.println("i3!=i4");
            }
            
         }
    }
    输出:
    i1==i2
    i3==i4

    Integer有个内部类IntegerCache,它维护了一个Integer数组cache[] ,长度为256,还有一个静态块 
    static { 
          for(int i = 0; i < cache.length; i++) 
                    cache[i] = new Integer(i - 128); 

    很明显这个静态块已经默认认创建出了-128~127 的 Integer 数据
      

  27.   

    因为int转换为Integer有个自动装箱池,它的范围是-128~127,只要是在这个范围的数都直接从自动装箱池拿,所以
    i1=100,i2=100是相等,而i3=200,i4=200不在自动装箱池,只能new,所以不等
      

  28.   

    有意思,这可能就是java的封箱和装箱没有做好吧
      

  29.   

    个人猜想,这类问题java标准上应有说明。
      

  30.   

    哥哥,Integer是对象不是基础变量,如果用Integer1==Integer2的用的是引用,即地址比较,试问两个地址怎么可能是相同的,基本变量可以,但是如果是对象的话要这样:i1.equals(i2)而不能用i1==i2.
      

  31.   

    当JVM被启动之后,就会有以下几个池:
      int,char,short,byte,long,char是在5.0以后才有的
    这个代码中的Integer i=100;是因为有自动封装的,只要是在-128~+127之间的就可以直接从int池中找,==比较的是地址是否相同,池中的100是只有一个的,所以地址是肯定相等的,所以两个是相等的
     而200不在这个范围之内,它会指向堆里,所以是false
      

  32.   

    Integer i1 = 100;
    等同于
    Integer i1 = Integer.valueOf(128); java.lang.Integer中关于valueOf的源码: 
    public static Integer valueOf(int i) { 
       final int offset = 128; 
       if (i >= -128 && i <= 127) { 
          return IntegerCache.cache[i + offset]; 
       } 
       return new Integer(i); 

    就是说 如果int i,i的范围在i >= -128 && i <= 127范围之内 其地址空间没有变化,都指向同一地址。
    如果超出这个范围,也就不在缓存的范围之内,其地址空间指向也会不同,立(Integer i3 = 200 会变成 Integer i3 = new Integer(200))。
    在JDK5一下 这样的定义Integer i1 = 127会抱错。