Java装箱拆箱原理
简言而之,java装箱即java编译器将基本数据类型自动转换成其包装类,拆箱即包装类自动转换成基本类型。特别比较a = Integer(0),b=Integer(0),c=0的数值问题时:
a != b ,
b ==c,
a==c,
a.equals©
均为true。原因在于==是直接比较内存地址,而基本类型包装类重写了Object类equals方法。 当基本类型封装类与基本类型比较时,可以通过分析javap -verbose命令对编译生成的字节码文件分析:
1、a.equals©会先对常量调用Integer.valueOf©进行装箱成Integer,然后再调用,equals方法进行转换成int类型比较。
2、a == c,java编译会对包装类进行拆箱,转成a.intValue()基本数据类型常量再比较,以下为代码字节码:
public void testInteger();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=1
0: iconst_0
1: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
4: astore_1
5: aconst_null
6: astore_2
7: aload_1
8: iconst_0
9: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;**
12: invokevirtual #3 // Method java/lang/Integer.equals:(Ljava/lang/Object;)
15: ifeq 26
18: getstatic #4// Field java/lang/System.out:Ljava/io/PrintStream;
21: ldc #5 // String a == 0
23: invokevirtual #6// Method java/io/PrintStream.println:(Ljava/lang/String;)V
26: aload_1
27: invokevirtual #7 // Method java/lang/Integer.intValue:()I
30: ifne 41
33: getstatic #4// Field java/lang/System.out:Ljava/io/PrintStream;
36: ldc #5 // String a == 0
38: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
41: return