《深入理解Java虚拟机》中讲语法糖时,提到了下面这个例子(不是原文中的例子,我自己改过):

  1. public class AutoBoxingTest {
  2.  
  3. /**
  4. * @param args
  5. */
  6. public static void main(String[] args) {
  7. Integer a = 1;
  8. Integer b = 2;
  9. Integer c = 127;
  10. Integer d = 127;
  11. Integer e = 3;
  12. Integer f = 3;
  13. Long g = 3L;
  14. System.out.println(c == d);
  15. System.out.println(e == f);
  16. System.out.println(e == (a + b));
  17. System.out.println(e.equals(a + b));
  18. System.out.println(g == (a + b));
  19. System.out.println(g.equals(a + b));
  20. }
  21. }

输出结果:

true

true

true

true

true

false

使用JAD反编译后,结果:

  1. import java.io.PrintStream;
  2.  
  3. public class AutoBoxingTest
  4. {
  5.  
  6. public AutoBoxingTest()
  7. {
  8. // 0 0:aload_0
  9. // 1 1:invokespecial #1 <Method void Object()>
  10. // 2 4:return
  11. }
  12.  
  13. public static void main(String args[])
  14. {
  15. Integer integer = Integer.valueOf(1);
  16. // 0 0:iconst_1
  17. // 1 1:invokestatic #2 <Method Integer Integer.valueOf(int)>
  18. // 2 4:astore_1
  19. Integer integer1 = Integer.valueOf(2);
  20. // 3 5:iconst_2
  21. // 4 6:invokestatic #2 <Method Integer Integer.valueOf(int)>
  22. // 5 9:astore_2
  23. Integer integer2 = Integer.valueOf(127);
  24. // 6 10:bipush 127
  25. // 7 12:invokestatic #2 <Method Integer Integer.valueOf(int)>
  26. // 8 15:astore_3
  27. Integer integer3 = Integer.valueOf(127);
  28. // 9 16:bipush 127
  29. // 10 18:invokestatic #2 <Method Integer Integer.valueOf(int)>
  30. // 11 21:astore 4
  31. Integer integer4 = Integer.valueOf(3);
  32. // 12 23:iconst_3
  33. // 13 24:invokestatic #2 <Method Integer Integer.valueOf(int)>
  34. // 14 27:astore 5
  35. Integer integer5 = Integer.valueOf(3);
  36. // 15 29:iconst_3
  37. // 16 30:invokestatic #2 <Method Integer Integer.valueOf(int)>
  38. // 17 33:astore 6
  39. Long long1 = Long.valueOf(3L);
  40. // 18 35:ldc2w #3 <Long 3L>
  41. // 19 38:invokestatic #5 <Method Long Long.valueOf(long)>
  42. // 20 41:astore 7
  43. System.out.println(integer2 == integer3);
  44. // 21 43:getstatic #6 <Field PrintStream System.out>
  45. // 22 46:aload_3
  46. // 23 47:aload 4
  47. // 24 49:if_acmpne 56
  48. // 25 52:iconst_1
  49. // 26 53:goto 57
  50. // 27 56:iconst_0
  51. // 28 57:invokevirtual #7 <Method void PrintStream.println(boolean)>
  52. System.out.println(integer4 == integer5);
  53. // 29 60:getstatic #6 <Field PrintStream System.out>
  54. // 30 63:aload 5
  55. // 31 65:aload 6
  56. // 32 67:if_acmpne 74
  57. // 33 70:iconst_1
  58. // 34 71:goto 75
  59. // 35 74:iconst_0
  60. // 36 75:invokevirtual #7 <Method void PrintStream.println(boolean)>
  61. System.out.println(integer4.intValue() == integer.intValue() + integer1.intValue());
  62. // 37 78:getstatic #6 <Field PrintStream System.out>
  63. // 38 81:aload 5
  64. // 39 83:invokevirtual #8 <Method int Integer.intValue()>
  65. // 40 86:aload_1
  66. // 41 87:invokevirtual #8 <Method int Integer.intValue()>
  67. // 42 90:aload_2
  68. // 43 91:invokevirtual #8 <Method int Integer.intValue()>
  69. // 44 94:iadd
  70. // 45 95:icmpne 102
  71. // 46 98:iconst_1
  72. // 47 99:goto 103
  73. // 48 102:iconst_0
  74. // 49 103:invokevirtual #7 <Method void PrintStream.println(boolean)>
  75. System.out.println(integer4.equals(Integer.valueOf(integer.intValue() + integer1.intValue())));
  76. // 50 106:getstatic #6 <Field PrintStream System.out>
  77. // 51 109:aload 5
  78. // 52 111:aload_1
  79. // 53 112:invokevirtual #8 <Method int Integer.intValue()>
  80. // 54 115:aload_2
  81. // 55 116:invokevirtual #8 <Method int Integer.intValue()>
  82. // 56 119:iadd
  83. // 57 120:invokestatic #2 <Method Integer Integer.valueOf(int)>
  84. // 58 123:invokevirtual #9 <Method boolean Integer.equals(Object)>
  85. // 59 126:invokevirtual #7 <Method void PrintStream.println(boolean)>
  86. System.out.println(long1.longValue() == (long)(integer.intValue() + integer1.intValue()));
  87. // 60 129:getstatic #6 <Field PrintStream System.out>
  88. // 61 132:aload 7
  89. // 62 134:invokevirtual #10 <Method long Long.longValue()>
  90. // 63 137:aload_1
  91. // 64 138:invokevirtual #8 <Method int Integer.intValue()>
  92. // 65 141:aload_2
  93. // 66 142:invokevirtual #8 <Method int Integer.intValue()>
  94. // 67 145:iadd
  95. // 68 146:i2l
  96. // 69 147:lcmp
  97. // 70 148:ifne 155
  98. // 71 151:iconst_1
  99. // 72 152:goto 156
  100. // 73 155:iconst_0
  101. // 74 156:invokevirtual #7 <Method void PrintStream.println(boolean)>
  102. System.out.println(long1.equals(Integer.valueOf(integer.intValue() + integer1.intValue())));
  103. // 75 159:getstatic #6 <Field PrintStream System.out>
  104. // 76 162:aload 7
  105. // 77 164:aload_1
  106. // 78 165:invokevirtual #8 <Method int Integer.intValue()>
  107. // 79 168:aload_2
  108. // 80 169:invokevirtual #8 <Method int Integer.intValue()>
  109. // 81 172:iadd
  110. // 82 173:invokestatic #2 <Method Integer Integer.valueOf(int)>
  111. // 83 176:invokevirtual #11 <Method boolean Long.equals(Object)>
  112. // 84 179:invokevirtual #7 <Method void PrintStream.println(boolean)>
  113. // 85 182:return
  114. }
  115. }

从中可以看出,最后false产生的原因是Long类型和Integer进行比较,不同类型自然不会equal了。

另外,原文中使用的是321而不是127,这样做java的字节码中将使用sipush而不是bipush,此时==判断会变为false,目前我不太明白为啥会这样,望大神指点。

Java中自动装箱代码初探的更多相关文章

  1. java中自动装箱带来的性能问题

    之前没有特别注意自动封装所带来的性能问题,今天看了effective java,实验了一下,结果大吃一惊: 考虑下面这段代码: public static void main(String args[ ...

  2. Java中自动装箱与拆箱

    一.什么是封装类? Java中存在基础数据类型,但是在某些情况下,我们要对基础数据类型进行对象的操作,例如,集合中只能存在对象,而不能存在基础数据类型,于是便出现了包装器类.包装器类型就是对基本数据类 ...

  3. java中自动装箱的问题

    package wrapper; public class WrapperDemo { public static void main(String[] args) { Integer a=new I ...

  4. 深入剖析Java中的装箱和拆箱

    深入剖析Java中的装箱和拆箱 自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就来一些看一下装箱和拆箱中的若干问题.本文先讲述装箱和拆箱最基本的东西,再来看一下面试笔试中经常遇到的与装箱 ...

  5. 从别人那淘的知识 深入剖析Java中的装箱和拆箱

    (转载的海子的博文   海子:http://www.cnblogs.com/dolphin0520/) 深入剖析Java中的装箱和拆箱 自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就来 ...

  6. 第六节:详细讲解Java中的装箱与拆箱及其字符串

    前言 大家好,给大家带来详细讲解Java中的装箱与拆箱及其字符串的概述,希望你们喜欢 装箱与拆箱 封装类有:Byte , short , Integer , Character , long , Fl ...

  7. [ 转载 ]学习笔记-深入剖析Java中的装箱和拆箱

    深入剖析Java中的装箱和拆箱 自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就来一些看一下装箱和拆箱中的若干问题.本文先讲述装箱和拆箱最基本的东西,再来看一下面试笔试中经常遇到的与装箱 ...

  8. 【转】深入剖析Java中的装箱和拆箱

    深入剖析Java中的装箱和拆箱 自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就来一些看一下装箱和拆箱中的若干问题.本文先讲述装箱和拆箱最基本的东西,再来看一下面试笔试中经常遇到的与装箱 ...

  9. Java的自动装箱/拆箱

    概述 自JDK1.5开始, 引入了自动装箱/拆箱这一语法糖, 它使程序员的代码变得更加简洁, 不再需要进行显式转换.基本类型与包装类型在某些操作符的作用下, 包装类型调用valueOf()方法将原始类 ...

随机推荐

  1. SQL查询顺序

    SQL查询顺序 1 FROM 2 WHERE 3 SELECT 4 ORDER BY 5 GOUP BY 6 HAVING 左外连接:查询出 left join 左边表的全部数据,left join右 ...

  2. 【转】Vue.js:轻量高效的前端组件化方案

    摘要:Vue.js通过简洁的API提供高效的数据绑定和灵活的组件系统.在前端纷繁复杂的生态中,Vue.js有幸受到一定程度的关注,目前在GitHub上已经有5000+的star.本文将从各方面对Vue ...

  3. 派派和京东的paipai域名之争

    最近有一款叫“派派”的APP很火,微博上.电梯里.群里到处都是推广广告.不仅如此,还有大张伟.关晓彤.王祖蓝等十几个明星发帖为“派派”站台.有消息称,派派这段时间仅线上推广就花去了约1600万. 总融 ...

  4. Valid Parentheses有效括号匹配。利用栈。

    问题描述:给定一个字符串,其中只包含字符‘{’,    '}',    '[',    ']',   '(',    ')'确定如果输入字符串是有效的.括号必须以正确的顺序排列,“()”和“()[]{ ...

  5. jq中同个页面点击事件和回车事件

    button元素,绑定一系列事件的时候,点击-回车-回车,会出现错误. 解决办法,就是把button变成a 详情是,一个页面中有点击按钮,按钮点击之后,出现弹框1,点击弹框1的确定,出现弹框2,点击弹 ...

  6. 在java中public void与public static void区别

    static 方法可以被main方法直接调用,而非static方法不可以.因为static方法是属于类的,是类方法.可以通过类名.方法名直接调用.而非static方法必须等对象被new出来以后才能使用 ...

  7. 谷歌地图OGC WMTS服务规则

    http://mt0.google.cn/vt/lyrs=s&x=0&y=0&z=1 其中:z即为瓦片的层次,0层覆盖全球:y为行,从上往下为0~2^z-1:x为列,从左往右依 ...

  8. 配置JSP模板

  9. 一次应用js文件时遇到的怪异现象

    使用thinkphp开发的网页中, 应用js文件 <script  language="JavaScript"  src="__JS__/printer/jquer ...

  10. php开发工程师面必问题

    随着培训机构的增加,越来越多的php从业者流入市场,从而影响了php就业环境.公司对人才的要求越来越高,而技术者本身也要技术过硬,学习越来越多的东西,因为只有这样,你才能跑在别人前面,才不被市场抛弃, ...