Java自动装箱与拆箱

时间:2023-02-17 12:48:10

转载自:http://blog.csdn.net/u013256816/article/details/50802078

自动装箱与拆箱机制在实际使用中非常常见,不过也特别容易出错,博主在面对下面一道题的时候自信满满,可还是没有能够全对,所以写下这篇博文,给自己对自动装箱与拆箱机制做一下知识巩固,也给各位朋友做一下参考。 
  首先有这样一道题,给出下面代码的输出结果:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> AutoBoxing
{
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">main</span>(String[] args)
{
Integer a = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
Integer b = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>;
Integer c = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>;
Integer d = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>;
Integer e = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">321</span>;
Integer f = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">321</span>;
Long g = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>L;

System.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.println(c==d);
System.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.println(e==f);
System.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.println(c==(a+b));
System.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.println(c.equals(a+b));
System.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.println(g==(a+b));
System.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.println(g.equals(a+b));
}
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li></ul>

  运行结果:

<code class="hljs bash has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">true</span>
<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">false</span>
<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">true</span>
<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">true</span>
<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">true</span>
<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">false</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>

  如果你看到这边,答案都正确,而且没有丝毫的疑问,那么对于你来说这篇博文就此结束了,如果没有,请继续翻阅。


  首先从最基础的开始讲起,首先通过反编译来看一看自动装箱和拆箱的过程: 
  首先看如下一段程序:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> AutoBoxing2
{
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">main</span>(String[] args)
{
Integer a = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
Integer b = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>;
Integer c = a+b;
}
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>

  反编译结果为:(如果对于java反编译不太了解的朋友可以先看一下《通过Java反编译揭开一些问题的真相》)

<code class="hljs mathematica has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">public jvm.optimize.AutoBoxing2();
flags: ACC_PUBLIC

Code:
stack=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, locals=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, args_size=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>
<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>: aload_0
<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>: invokespecial #<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> // <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Method</span> java/lang/Object.<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"<init>"</span>:()V
<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>: return
LineNumberTable:
line <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>: <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>

public static void main(java.lang.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">String</span>[]);
flags: ACC_PUBLIC, ACC_STATIC

Code:
stack=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, locals=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>, args_size=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>
<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>: iconst_1
<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>: invokestatic #<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span> // <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Method</span> java/lang/<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Integer</span>.valueOf:(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">I</span>)Ljava/lang/<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Integer</span>;
<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>: astore_1
<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>: iconst_2
<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">6</span>: invokestatic #<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span> // <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Method</span> java/lang/<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Integer</span>.valueOf:(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">I</span>)Ljava/lang/<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Integer</span>;
<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">9</span>: astore_2
<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>: aload_1
<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">11</span>: invokevirtual #<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span> // <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Method</span> java/lang/<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Integer</span>.intValue:()<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">I</span>
<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">14</span>: aload_2
<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">15</span>: invokevirtual #<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span> // <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Method</span> java/lang/<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Integer</span>.intValue:()<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">I</span>
<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">18</span>: iadd
<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">19</span>: invokestatic #<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span> // <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Method</span> java/lang/<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Integer</span>.valueOf:(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">I</span>)Ljava/lang/<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Integer</span>;
<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">22</span>: astore_3
<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">23</span>: return
LineNumberTable:
line <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span>: <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>
line <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">9</span>: <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>
line <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>: <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>
line <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">11</span>: <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">23</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li></ul>

  可以看到Integer a=1实际上自动装箱为Integer a = Integer.valueOf(1),而在进行a+b的时候可以看到进行了自动拆箱,将a拆箱为Integer.intValue();然后将a和b的int值相加,相加之后有进行了自动装箱:Integer c=Integer.valueOf(3).


  接下来我们就可以上面题目中给出的 System.out.println(c==d);和System.out.println(e==f);他们分别的结果为true和false。 
  知道Integer会缓存-128至127的朋友估计这两条语句的输出结果都能答对。 
  如果没有答对,请看解析: 
  Integer c=3;会自动装箱为Integer c = Integer.valueOf(3),那么看一下valueOf方法的源码:

<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> Integer <span class="hljs-title" style="box-sizing: border-box;">valueOf</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">assert</span> IntegerCache.high >= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">127</span>;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (i >= IntegerCache.low && i <= IntegerCache.high)
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> IntegerCache.cache[i + (-IntegerCache.low)];
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Integer(i);
}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">IntegerCache</span> {</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> low = -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">128</span>;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> high;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> Integer cache[];

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> {
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// high value may be configured by property</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> h = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">127</span>;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"java.lang.Integer.IntegerCache.high"</span>);
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (integerCacheHighPropValue != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = parseInt(integerCacheHighPropValue);
i = Math.max(i, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">127</span>);
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Maximum array size is Integer.MAX_VALUE</span>
h = Math.min(i, Integer.MAX_VALUE - (-low) -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>);
}
high = h;

cache = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Integer[(high - low) + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>];
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> j = low;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> k = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; k < cache.length; k++)
cache[k] = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Integer(j++);
}

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-title" style="box-sizing: border-box;">IntegerCache</span>() {}
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li></ul>

  可以看到实际上Integer会缓存-128值127的内容,如果值在这个区间之内(比如c和d),那么就会返回IntegerCache中的引用,所以Integer c= Integer d = IntegerCache.cache[3+(–128)] = IntegerCache.cache[131], c和d是相等的。 
  但是如果超过这个区间,比如e和f,则Integer e = new Integer(321); Integer f = new Integer(321);new出来的自然是在堆中新开辟的内存,两份地址不同,自然e和f不同,也就是如果遇到这样的情况:

<code class="hljs vhdl has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-typename" style="color: rgb(102, 0, 102); box-sizing: border-box;">Integer</span> m = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> <span class="hljs-typename" style="color: rgb(102, 0, 102); box-sizing: border-box;">Integer</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>);
<span class="hljs-typename" style="color: rgb(102, 0, 102); box-sizing: border-box;">Integer</span> n = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> <span class="hljs-typename" style="color: rgb(102, 0, 102); box-sizing: border-box;">Integer</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>);
System.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.println(m==n);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

  那么输出的结果是false(如果Integer m=2; Intger n=2则m和n相同)


  接着再说System.out.println(c==(a+b)); 
  我们看如下代码:

<code class="hljs vhdl has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-typename" style="color: rgb(102, 0, 102); box-sizing: border-box;">Integer</span> a = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
<span class="hljs-typename" style="color: rgb(102, 0, 102); box-sizing: border-box;">Integer</span> b = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>;
<span class="hljs-typename" style="color: rgb(102, 0, 102); box-sizing: border-box;">Integer</span> c = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>;
System.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.println(c==(a+b));</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>

  反编译之后:

<code class="hljs http has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">          <span class="hljs-attribute" style="box-sizing: border-box;">0</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">iconst_1      </span>
<span class="hljs-attribute" style="box-sizing: border-box;">1</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;</span>
<span class="hljs-attribute" style="box-sizing: border-box;">4</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">astore_1 </span>
<span class="hljs-attribute" style="box-sizing: border-box;">5</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">iconst_2 </span>
<span class="hljs-attribute" style="box-sizing: border-box;">6</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;</span>
<span class="hljs-attribute" style="box-sizing: border-box;">9</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">astore_2 </span>
<span class="hljs-attribute" style="box-sizing: border-box;">10</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">iconst_3 </span>
<span class="hljs-attribute" style="box-sizing: border-box;">11</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;</span>
<span class="hljs-attribute" style="box-sizing: border-box;">14</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">astore_3 </span>
<span class="hljs-attribute" style="box-sizing: border-box;">15</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;</span>
<span class="hljs-attribute" style="box-sizing: border-box;">18</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">aload_3 </span>
<span class="hljs-attribute" style="box-sizing: border-box;">19</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">invokevirtual #4 // Method java/lang/Integer.intValue:()I</span>
<span class="hljs-attribute" style="box-sizing: border-box;">22</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">aload_1 </span>
<span class="hljs-attribute" style="box-sizing: border-box;">23</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">invokevirtual #4 // Method java/lang/Integer.intValue:()I</span>
<span class="hljs-attribute" style="box-sizing: border-box;">26</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">aload_2 </span>
<span class="hljs-attribute" style="box-sizing: border-box;">27</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">invokevirtual #4 // Method java/lang/Integer.intValue:()I</span>
<span class="hljs-attribute" style="box-sizing: border-box;">30</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">iadd </span>
<span class="hljs-attribute" style="box-sizing: border-box;">31</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">if_icmpne 38</span>
<span class="hljs-attribute" style="box-sizing: border-box;">34</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">iconst_1 </span>
<span class="hljs-attribute" style="box-sizing: border-box;">35</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">goto 39</span>
<span class="hljs-attribute" style="box-sizing: border-box;">38</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">iconst_0 </span>
<span class="hljs-attribute" style="box-sizing: border-box;">39</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">invokevirtual #5 // Method java/io/PrintStream.println:(Z)V</span>
<span class="hljs-attribute" style="box-sizing: border-box;">42</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">return </span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li></ul>

  可以看到实际在c==(a+b)的时候是执行拆箱机制,实际上就是在运算3==2+1,当然就是true咯。


  继续说明: System.out.println(c.equals(a+b)); 
  同样看一下c.equals(a+b)反编译的结果(篇幅限制,只截取部分相关的结果):

<code class="hljs http has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">        <span class="hljs-attribute" style="box-sizing: border-box;">19</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">aload_1       </span>
<span class="hljs-attribute" style="box-sizing: border-box;">20</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">invokevirtual #4 // Method java/lang/Integer.intValue:()I</span>
<span class="hljs-attribute" style="box-sizing: border-box;">23</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">aload_2 </span>
<span class="hljs-attribute" style="box-sizing: border-box;">24</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">invokevirtual #4 // Method java/lang/Integer.intValue:()I</span>
<span class="hljs-attribute" style="box-sizing: border-box;">27</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">iadd </span>
<span class="hljs-attribute" style="box-sizing: border-box;">28</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;</span>
<span class="hljs-attribute" style="box-sizing: border-box;">31</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">invokevirtual #5 // Method java/lang/Integer.equals:(Ljava/lang/Object;)Z</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

  可以看到a+b先拆箱为int再相加之后再装箱为Integer型与c进行equals比较,那么我们再看一下equals()方法的源码:

<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">equals</span>(Object obj) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (obj <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">instanceof</span> Integer) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> value == ((Integer)obj).intValue();
}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>

  通过查看源码可知此条语句的输出结果为true。


  最后来看一下System.out.println(g==(a+b));和System.out.println(g.equals(a+b));两条语句。 
  System.out.println(g==(a+b));由前面的推论可知最后g拆箱为long型,a+b为int型,基础类型int可以自动升级为long,所以输出为true。 
  对于System.out.println(g.equals(a+b));可以看一下Long的equals()方法。

<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">equals</span>(Object obj) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (obj <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">instanceof</span> Long) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> value == ((Long)obj).longValue();
}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>

  对于(a+b)来说是Integer类型,所以返回false. 
  鉴于包装类的“==”运算在不遇到算术运算的情况下不会自动拆箱,以及它们equals()方法不处理数据转型的关系,博主建议在实际编码中要尽量避免这样使用自动装箱与拆箱机制。