【java】Integer == Integer?

  1. /** 
  2.  *本文出处:http://blog.csdn.net/zhoumingp/article/details/8298566
  3.  *Q:Integer和Integer对象用  == 进行比较的过程是怎样的? 
  4.  * 
  5.  *看例子 
  6.  */  
  7. public class Test {  
  8.   
  9.     public static void main(String[] args) {  
  10.         int a = 1;  
  11.         int b = 1;  
  12.         Integer c = 3;  
  13.         Integer d = 3;  
  14.         Integer e = 321;  
  15.         Integer f = 321;  
  16.   
  17.         System.out.println(a == b);  
  18.         System.out.println(c == d);  
  19.         System.out.println(e == f);  
  20.   
  21.     }  
  22. }  
  23. output:  
  24. true  
  25. true  
  26. false  
  27.   
  28. 下面具体解释三个结果  
  29. 通过java命令   javap -c 得到下面的字节码  
  30.   
  31.  Compiled from "Test.java"  
  32. public class Test extends java.lang.Object{  
  33. public Test();  
  34.   Code:  
  35.    0:   aload_0  
  36.    1:   invokespecial   #1//Method java/lang/Object."<init>":()V  
  37.    4:   return  
  38.   
  39. public static void main(java.lang.String[]);  
  40.   Code:  
  41.    0:   iconst_1  //将int类型常量1压入栈   
  42.    1:   istore_1  //将int类型值存入局部变量1  
  43.    2:   iconst_1  //将int类型常量1压入栈  
  44.    3:   istore_2  //将int类型值存入局部变量2  
  45.    4:   iconst_3  //将int类型常量3压入栈  
  46.    5:   invokestatic    #2//Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; //调用Integer的静态方法 valueOf,构建整型值为3的Integer对象  
  47.    8:   astore_3  //将引用存入局部变量3  
  48.    9:   iconst_3  
  49.    10:  invokestatic    #2//Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;  
  50.    13:  astore  4  
  51.    15:  sipush  321  //将321压入栈  
  52.    18:  invokestatic    #2//Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;  
  53.    21:  astore  5  
  54.    23:  sipush  321  
  55.    26:  invokestatic    #2//Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;  
  56.    29:  astore  6  
  57.    31:  getstatic       #3//Field java/lang/System.out:Ljava/io/PrintStream;  
  58.    34:  iload_1   //从局部变量1中装载int类型值到栈  
  59.    35:  iload_2  
  60.    36:  if_icmpne       43  //从栈中pop出两个int类型值并进行大小比较  
  61.    39:  iconst_1  
  62.    40:  goto    44  
  63.    43:  iconst_0  
  64.    44:  invokevirtual   #4//Method java/io/PrintStream.println:(Z)V  
  65.    47:  getstatic       #3//Field java/lang/System.out:Ljava/io/PrintStream;  
  66.    50:  aload_3   //从局部变量3中装载引用到栈  
  67.    51:  aload   4  
  68.    53:  if_acmpne       60   //从栈中pop出两个引用值进行比较  
  69.    56:  iconst_1  
  70.    57:  goto    61  
  71.    60:  iconst_0  
  72.    61:  invokevirtual   #4//Method java/io/PrintStream.println:(Z)V  
  73.    64:  getstatic       #3//Field java/lang/System.out:Ljava/io/PrintStream;  
  74.    67:  aload   5  
  75.    69:  aload   6  
  76.    71:  if_acmpne       78  
  77.    74:  iconst_1  
  78.    75:  goto    79  
  79.    78:  iconst_0  
  80.    79:  invokevirtual   #4//Method java/io/PrintStream.println:(Z)V  
  81.    82:  return  
  82.   
  83. }  
  84.   
  85.   
  86. 整型值的比较很容易理解,就是值的大小比较  
  87.   
  88. 但是为什么下面的语句会是不同的结果:  
  89.   
  90.         System.out.println(c == d);  
  91.         System.out.println(e == f);  
  92.   
  93. 从字节码上看都是一样的指令,没有不同的地方  
  94. 原因就在Integer的方法 valueOf  
  95.   
  96. 我们来看这个方法的源码:字节码里调用的就是这个方法:   
  97.   
  98.  public static Integer valueOf(int i) {  
  99.         if(i >= -128 && i <= IntegerCache.high)  
  100.             return IntegerCache.cache[i + 128];  
  101.         else  
  102.             return new Integer(i);  
  103.     }  
  104.   
  105. private static class IntegerCache {  
  106.         static final int high;  
  107.         static final Integer cache[];  
  108.   
  109.         static {  
  110.             final int low = -128;  
  111.   
  112.             // high value may be configured by property  
  113.             int h = 127;  
  114.             if (integerCacheHighPropValue != null) {  
  115.                 // Use Long.decode here to avoid invoking methods that  
  116.                 // require Integer's autoboxing cache to be initialized  
  117.                 int i = Long.decode(integerCacheHighPropValue).intValue();  
  118.                 i = Math.max(i, 127);  
  119.                 // Maximum array size is Integer.MAX_VALUE  
  120.                 h = Math.min(i, Integer.MAX_VALUE - -low);  
  121.             }  
  122.             high = h;  
  123.   
  124.             cache = new Integer[(high - low) + 1];  
  125.             int j = low;  
  126.             for(int k = 0; k < cache.length; k++)  
  127.                 cache[k] = new Integer(j++);  
  128.         }  
  129.   
  130.         private IntegerCache() {}  
  131.     }  
  132.   
  133. Integer里弄了一个缓存,对于在 -128127 之间的数值,会直接使用该缓存里的对象  
  134.  也就是说 Integer c = 3 或者 Integer c = Integer.valueOf(3) ,最终 c 得到的是Integer里的缓存对象  
  135.  同理,d也是获得该相同对象因此 进行 c == d 比较时,c和d引用的是同一个对象,因此就true  
  136.  而对于321,已经超出缓存范围了,因此 valueOf 方法会生成一个新的Integer对象因此e和f就引用不同 的对象了,进行==比较,当然就false了  
  137.  另外,对Integer的缓存,我们在日常开发时,对于小的整型值应该充分利用Integer的缓存对象省去过多的对象创建,回收的操作,这样会极大的提高程序性能 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值