Java中自动装箱代码初探

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

public class AutoBoxingTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Integer a = 1;
		Integer b = 2;
		Integer c = 127;
		Integer d = 127;
		Integer e = 3;
		Integer f = 3;
		Long g = 3L;
		System.out.println(c == d); 
		System.out.println(e == f);
		System.out.println(e == (a + b));
		System.out.println(e.equals(a + b));
		System.out.println(g == (a + b));
		System.out.println(g.equals(a + b));
	}
}
输出结果:

true
true
true
true
true
false
使用JAD反编译后,结果:

import java.io.PrintStream;

public class AutoBoxingTest
{

    public AutoBoxingTest()
    {
    //    0    0:aload_0         
    //    1    1:invokespecial   #1   <Method void Object()>
    //    2    4:return          
    }

    public static void main(String args[])
    {
        Integer integer = Integer.valueOf(1);
    //    0    0:iconst_1        
    //    1    1:invokestatic    #2   <Method Integer Integer.valueOf(int)>
    //    2    4:astore_1        
        Integer integer1 = Integer.valueOf(2);
    //    3    5:iconst_2        
    //    4    6:invokestatic    #2   <Method Integer Integer.valueOf(int)>
    //    5    9:astore_2        
        Integer integer2 = Integer.valueOf(127);
    //    6   10:bipush          127
    //    7   12:invokestatic    #2   <Method Integer Integer.valueOf(int)>
    //    8   15:astore_3        
        Integer integer3 = Integer.valueOf(127);
    //    9   16:bipush          127
    //   10   18:invokestatic    #2   <Method Integer Integer.valueOf(int)>
    //   11   21:astore          4
        Integer integer4 = Integer.valueOf(3);
    //   12   23:iconst_3        
    //   13   24:invokestatic    #2   <Method Integer Integer.valueOf(int)>
    //   14   27:astore          5
        Integer integer5 = Integer.valueOf(3);
    //   15   29:iconst_3        
    //   16   30:invokestatic    #2   <Method Integer Integer.valueOf(int)>
    //   17   33:astore          6
        Long long1 = Long.valueOf(3L);
    //   18   35:ldc2w           #3   <Long 3L>
    //   19   38:invokestatic    #5   <Method Long Long.valueOf(long)>
    //   20   41:astore          7
        System.out.println(integer2 == integer3);
    //   21   43:getstatic       #6   <Field PrintStream System.out>
    //   22   46:aload_3         
    //   23   47:aload           4
    //   24   49:if_acmpne       56
    //   25   52:iconst_1        
    //   26   53:goto            57
    //   27   56:iconst_0        
    //   28   57:invokevirtual   #7   <Method void PrintStream.println(boolean)>
        System.out.println(integer4 == integer5);
    //   29   60:getstatic       #6   <Field PrintStream System.out>
    //   30   63:aload           5
    //   31   65:aload           6
    //   32   67:if_acmpne       74
    //   33   70:iconst_1        
    //   34   71:goto            75
    //   35   74:iconst_0        
    //   36   75:invokevirtual   #7   <Method void PrintStream.println(boolean)>
        System.out.println(integer4.intValue() == integer.intValue() + integer1.intValue());
    //   37   78:getstatic       #6   <Field PrintStream System.out>
    //   38   81:aload           5
    //   39   83:invokevirtual   #8   <Method int Integer.intValue()>
    //   40   86:aload_1         
    //   41   87:invokevirtual   #8   <Method int Integer.intValue()>
    //   42   90:aload_2         
    //   43   91:invokevirtual   #8   <Method int Integer.intValue()>
    //   44   94:iadd            
    //   45   95:icmpne          102
    //   46   98:iconst_1        
    //   47   99:goto            103
    //   48  102:iconst_0        
    //   49  103:invokevirtual   #7   <Method void PrintStream.println(boolean)>
        System.out.println(integer4.equals(Integer.valueOf(integer.intValue() + integer1.intValue())));
    //   50  106:getstatic       #6   <Field PrintStream System.out>
    //   51  109:aload           5
    //   52  111:aload_1         
    //   53  112:invokevirtual   #8   <Method int Integer.intValue()>
    //   54  115:aload_2         
    //   55  116:invokevirtual   #8   <Method int Integer.intValue()>
    //   56  119:iadd            
    //   57  120:invokestatic    #2   <Method Integer Integer.valueOf(int)>
    //   58  123:invokevirtual   #9   <Method boolean Integer.equals(Object)>
    //   59  126:invokevirtual   #7   <Method void PrintStream.println(boolean)>
        System.out.println(long1.longValue() == (long)(integer.intValue() + integer1.intValue()));
    //   60  129:getstatic       #6   <Field PrintStream System.out>
    //   61  132:aload           7
    //   62  134:invokevirtual   #10  <Method long Long.longValue()>
    //   63  137:aload_1         
    //   64  138:invokevirtual   #8   <Method int Integer.intValue()>
    //   65  141:aload_2         
    //   66  142:invokevirtual   #8   <Method int Integer.intValue()>
    //   67  145:iadd            
    //   68  146:i2l             
    //   69  147:lcmp            
    //   70  148:ifne            155
    //   71  151:iconst_1        
    //   72  152:goto            156
    //   73  155:iconst_0        
    //   74  156:invokevirtual   #7   <Method void PrintStream.println(boolean)>
        System.out.println(long1.equals(Integer.valueOf(integer.intValue() + integer1.intValue())));
    //   75  159:getstatic       #6   <Field PrintStream System.out>
    //   76  162:aload           7
    //   77  164:aload_1         
    //   78  165:invokevirtual   #8   <Method int Integer.intValue()>
    //   79  168:aload_2         
    //   80  169:invokevirtual   #8   <Method int Integer.intValue()>
    //   81  172:iadd            
    //   82  173:invokestatic    #2   <Method Integer Integer.valueOf(int)>
    //   83  176:invokevirtual   #11  <Method boolean Long.equals(Object)>
    //   84  179:invokevirtual   #7   <Method void PrintStream.println(boolean)>
    //   85  182:return          
    }
}
从中可以看出,最后false产生的原因是Long类型和Integer进行比较,不同类型自然不会equal了。


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

原文地址:https://www.cnblogs.com/jubincn/p/3381100.html