读书人

Integer == Integer

发布时间: 2013-04-09 16:45:09 作者: rapoo

Integer == Integer?
Integer == Integer?

/**  *Q:Integer和Integer对象用  == 进行比较的过程是怎样的?  *  *看例子  */  public class Test {        public static void main(String[] args) {          int a = 1;          int b = 1;          Integer c = 3;          Integer d = 3;          Integer e = 321;          Integer f = 321;            System.out.println(a == b);          System.out.println(c == d);          System.out.println(e == f);        }  }  output:  true  true  false    下面具体解释三个结果  通过java命令   javap -c 得到下面的字节码     Compiled from "Test.java"  public class Test extends java.lang.Object{  public Test();    Code:     0:   aload_0     1:   invokespecial   #1; //Method java/lang/Object."<init>":()V     4:   return    public static void main(java.lang.String[]);    Code:     0:   iconst_1  //将int类型常量1压入栈      1:   istore_1  //将int类型值存入局部变量1     2:   iconst_1  //将int类型常量1压入栈     3:   istore_2  //将int类型值存入局部变量2     4:   iconst_3  //将int类型常量3压入栈     5:   invokestatic    #2; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; //调用Integer的静态方法 valueOf,构建整型值为3的Integer对象     8:   astore_3  //将引用存入局部变量3     9:   iconst_3     10:  invokestatic    #2; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;     13:  astore  4     15:  sipush  321  //将321压入栈     18:  invokestatic    #2; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;     21:  astore  5     23:  sipush  321     26:  invokestatic    #2; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;     29:  astore  6     31:  getstatic       #3; //Field java/lang/System.out:Ljava/io/PrintStream;     34:  iload_1   //从局部变量1中装载int类型值到栈     35:  iload_2     36:  if_icmpne       43  //从栈中pop出两个int类型值并进行大小比较     39:  iconst_1     40:  goto    44     43:  iconst_0     44:  invokevirtual   #4; //Method java/io/PrintStream.println:(Z)V     47:  getstatic       #3; //Field java/lang/System.out:Ljava/io/PrintStream;     50:  aload_3   //从局部变量3中装载引用到栈     51:  aload   4     53:  if_acmpne       60   //从栈中pop出两个引用值进行比较     56:  iconst_1     57:  goto    61     60:  iconst_0     61:  invokevirtual   #4; //Method java/io/PrintStream.println:(Z)V     64:  getstatic       #3; //Field java/lang/System.out:Ljava/io/PrintStream;     67:  aload   5     69:  aload   6     71:  if_acmpne       78     74:  iconst_1     75:  goto    79     78:  iconst_0     79:  invokevirtual   #4; //Method java/io/PrintStream.println:(Z)V     82:  return    }      整型值的比较很容易理解,就是值的大小比较    但是为什么下面的语句会是不同的结果:            System.out.println(c == d);          System.out.println(e == f);    从字节码上看都是一样的指令,没有不同的地方  原因就在Integer的方法 valueOf    我们来看这个方法的源码:字节码里调用的就是这个方法:      public static Integer valueOf(int i) {          if(i >= -128 && i <= IntegerCache.high)              return IntegerCache.cache[i + 128];          else              return new Integer(i);      }    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() {}      }    Integer里弄了一个缓存,对于在 -128—127 之间的数值,会直接使用该缓存里的对象   也就是说 Integer c = 3 或者 Integer c = Integer.valueOf(3) ,最终 c 得到的是Integer里的缓存对象   同理,d也是获得该相同对象因此 进行 c == d 比较时,c和d引用的是同一个对象,因此就true   而对于321,已经超出缓存范围了,因此 valueOf 方法会生成一个新的Integer对象因此e和f就引用不同 的对象了,进行==比较,当然就false了   另外,对Integer的缓存,我们在日常开发时,对于小的整型值应该充分利用Integer的缓存对象省去过多的对象创建,回收的操作,这样会极大的提高程序性能  

读书人网 >编程

热点推荐