最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Java装箱与拆箱详解及实例代码
时间:2017-01-11 编辑:简简单单 来源:一聚教程网
Java 装箱与拆箱详解
前言:
要理解装箱和拆箱的概念,就要理解Java数据类型
装箱:把基本类型用它们相应的引用类型包装起来,使其具有对象的性质。int包装成Integer、float包装成Float
拆箱:和装箱相反,将引用类型的对象简化成值类型的数据
Integer a =100; 这是自动装箱 (编译器调用的是staticInteger valueOf(inti)) int b =newInteger(100); 这是自动拆箱 |
看下面一段代码
m1
publicclassDataType {
publicstaticvoidmain(String args[]) { DataType dt =newDataType(); dt.m11(); dt.m12();
}
publicvoidm11() { Integer a =newInteger(100); Integer b =100; System.out.println("m11 result "+ (a == b)); }
publicvoidm12() { Integer a =newInteger(128); Integer b =128; System.out.println("m12 result "+ (a == b)); }
} |
打印结果是什么?
m11 resultfalse m12 resultfalse |
“==”比较的是地址,而a和b两个对象的地址不同,即是两个对象,所以都是false
通过javap解析字节码,内容如下
publicvoidm11(); Code: 0: new #44;//class java/lang/Integer 3: dup 4: bipush100 6: invokespecial #46;//Method java/lang/Integer." 9: astore_1 10: bipush100 12: invokestatic #49;//Method java/lang/Integer.valueOf:(I)Ljava/lang/In teger; 15: astore_2 16: getstatic #53;//Field java/lang/System.out:Ljava/io/PrintStream; 19:new #59;//class java/lang/StringBuilder 22: dup 23: ldc #61;//String m11 result 25: invokespecial #63;//Method java/lang/StringBuilder." ng/String;)V 28: aload_1 29: aload_2 30: if_acmpne 37 33: iconst_1 34:goto 38 37: iconst_0 38: invokevirtual #66;//Method java/lang/StringBuilder.append:(Z)Ljava/la ng/StringBuilder; 41: invokevirtual #70;//Method java/lang/StringBuilder.toString:()Ljava/l ang/String; 44: invokevirtual #74;//Method java/io/PrintStream.println:(Ljava/lang/St ring;)V 47:return
publicvoidm12(); Code: 0: new #44;//class java/lang/Integer 3: dup 4: sipush128 7: invokespecial #46;//Method java/lang/Integer." 10: astore_1 11: sipush128 14: invokestatic #49;//Method java/lang/Integer.valueOf:(I)Ljava/lang/In teger; 17: astore_2 18: getstatic #53;//Field java/lang/System.out:Ljava/io/PrintStream; 21:new #59;//class java/lang/StringBuilder 24: dup 25: ldc #82;//String m12 result 27: invokespecial #63;//Method java/lang/StringBuilder." ng/String;)V 30: aload_1 31: aload_2 32: if_acmpne 39 35: iconst_1 36:goto 40 39: iconst_0 40: invokevirtual #66;//Method java/lang/StringBuilder.append:(Z)Ljava/la ng/StringBuilder; 43: invokevirtual #70;//Method java/lang/StringBuilder.toString:()Ljava/l ang/String; 46: invokevirtual #74;//Method java/io/PrintStream.println:(Ljava/lang/St ring;)V 49:return
|
m2
publicclassDataType {
publicstaticvoidmain(String args[]) { DataType dt =newDataType(); dt.m21(); dt.m22(); }
publicvoidm21() { Integer a =newInteger(100); Integer b =newInteger(100); System.out.println("m21 result "+ (a == b)); }
publicvoidm22() { Integer a =newInteger(128); Integer b =newInteger(128); System.out.println("m22 result "+ (a == b)); }
} |
打印结果是
m21 resultfalse m22 resultfalse |
a和b仍是两个对象
javap解析内容
publicvoidm21(); Code: 0: new #44;//class java/lang/Integer 3: dup 4: bipush100 6: invokespecial #46;//Method java/lang/Integer." 9: astore_1 10:new #44;//class java/lang/Integer 13: dup 14: bipush100 16: invokespecial #46;//Method java/lang/Integer." 19: astore_2 20: getstatic #53;//Field java/lang/System.out:Ljava/io/PrintStream; 23:new #59;//class java/lang/StringBuilder 26: dup 27: ldc #84;//String m21 result 29: invokespecial #63;//Method java/lang/StringBuilder." ng/String;)V 32: aload_1 33: aload_2 34: if_acmpne 41 37: iconst_1 38:goto 42 41: iconst_0 42: invokevirtual #66;//Method java/lang/StringBuilder.append:(Z)Ljava/la ng/StringBuilder; 45: invokevirtual #70;//Method java/lang/StringBuilder.toString:()Ljava/l ang/String; 48: invokevirtual #74;//Method java/io/PrintStream.println:(Ljava/lang/St ring;)V 51:return
publicvoidm22(); Code: 0: new #44;//class java/lang/Integer 3: dup 4: sipush128 7: invokespecial #46;//Method java/lang/Integer." 10: astore_1 11:new #44;//class java/lang/Integer 14: dup 15: sipush128 18: invokespecial #46;//Method java/lang/Integer." 21: astore_2 22: getstatic #53;//Field java/lang/System.out:Ljava/io/PrintStream; 25:new #59;//class java/lang/StringBuilder 28: dup 29: ldc #86;//String m22 result 31: invokespecial #63;//Method java/lang/StringBuilder." ng/String;)V 34: aload_1 35: aload_2 36: if_acmpne 43 39: iconst_1 40:goto 44 43: iconst_0 44: invokevirtual #66;//Method java/lang/StringBuilder.append:(Z)Ljava/la ng/StringBuilder; 47: invokevirtual #70;//Method java/lang/StringBuilder.toString:()Ljava/l ang/String; 50: invokevirtual #74;//Method java/io/PrintStream.println:(Ljava/lang/St ring;)V 53:return |
m3
publicclassDataType {
publicstaticvoidmain(String args[]) { DataType dt =newDataType(); dt.m31(); dt.m32(); }
publicvoidm31() { Integer a =100; Integer b =100; System.out.println("m31 result "+ (a == b)); }
publicvoidm32() { Integer a =128; Integer b =128; System.out.println("m32 result "+ (a == b)); }
} |
打印结果
m31 resulttrue m32 resultfalse |
为什么有第一个是true,第二个是false呢?观察javap解析的数据
javap解析内容
publicvoidm31(); Code: 0: bipush100 2: invokestatic #49;//Method java/lang/Integer.valueOf:(I)Ljava/lang/In teger; 5: astore_1 6: bipush100 8: invokestatic #49;//Method java/lang/Integer.valueOf:(I)Ljava/lang/In teger; 11: astore_2 12: getstatic #53;//Field java/lang/System.out:Ljava/io/PrintStream; 15:new #59;//class java/lang/StringBuilder 18: dup 19: ldc #88;//String m31 result 21: invokespecial #63;//Method java/lang/StringBuilder." ng/String;)V 24: aload_1 25: aload_2 26: if_acmpne 33 29: iconst_1 30:goto 34 33: iconst_0 34: invokevirtual #66;//Method java/lang/StringBuilder.append:(Z)Ljava/la ng/StringBuilder; 37: invokevirtual #70;//Method java/lang/StringBuilder.toString:()Ljava/l ang/String; 40: invokevirtual #74;//Method java/io/PrintStream.println:(Ljava/lang/St ring;)V 43:return
publicvoidm32(); Code: 0: sipush128 3: invokestatic #49;//Method java/lang/Integer.valueOf:(I)Ljava/lang/In teger; 6: astore_1 7: sipush128 10: invokestatic #49;//Method java/lang/Integer.valueOf:(I)Ljava/lang/In teger; 13: astore_2 14: getstatic #53;//Field java/lang/System.out:Ljava/io/PrintStream; 17:new #59;//class java/lang/StringBuilder 20: dup 21: ldc #90;//String m32 result 23: invokespecial #63;//Method java/lang/StringBuilder." ng/String;)V 26: aload_1 27: aload_2 28: if_acmpne 35 31: iconst_1 32:goto 36 35: iconst_0 36: invokevirtual #66;//Method java/lang/StringBuilder.append:(Z)Ljava/la ng/StringBuilder; 39: invokevirtual #70;//Method java/lang/StringBuilder.toString:()Ljava/l ang/String; 42: invokevirtual #74;//Method java/io/PrintStream.println:(Ljava/lang/St ring;)V 45:return |
m4
publicclassDataType {
publicstaticvoidmain(String args[]) { DataType dt =newDataType(); dt.m41(); dt.m42(); }
publicvoidm41() { Integer a = Integer.valueOf(100); Integer b =100; System.out.println("m41 result "+ (a == b)); }
publicvoidm42() { Integer a = Integer.valueOf(128); Integer b =128; System.out.println("m42 result "+ (a == b)); } } |
打印结果
m41 resulttrue m42 resultfalse |
javap解析内容
publicvoidm41(); Code: 0: bipush100 2: invokestatic #49;//Method java/lang/Integer.valueOf:(I)Ljava/lang/In teger; 5: astore_1 6: bipush100 8: invokestatic #49;//Method java/lang/Integer.valueOf:(I)Ljava/lang/In teger; 11: astore_2 12: getstatic #53;//Field java/lang/System.out:Ljava/io/PrintStream; 15:new #59;//class java/lang/StringBuilder 18: dup 19: ldc #92;//String m41 result 21: invokespecial #63;//Method java/lang/StringBuilder." ng/String;)V 24: aload_1 25: aload_2 26: if_acmpne 33 29: iconst_1 30:goto 34 33: iconst_0 34: invokevirtual #66;//Method java/lang/StringBuilder.append:(Z)Ljava/la ng/StringBuilder; 37: invokevirtual #70;//Method java/lang/StringBuilder.toString:()Ljava/l ang/String; 40: invokevirtual #74;//Method java/io/PrintStream.println:(Ljava/lang/St ring;)V 43:return
publicvoidm42(); Code: 0: sipush128 3: invokestatic #49;//Method java/lang/Integer.valueOf:(I)Ljava/lang/In teger; 6: astore_1 7: sipush128 10: invokestatic #49;//Method java/lang/Integer.valueOf:(I)Ljava/lang/In teger; 13: astore_2 14: getstatic #53;//Field java/lang/System.out:Ljava/io/PrintStream; 17:new #59;//class java/lang/StringBuilder 20: dup 21: ldc #94;//String m42 result 23: invokespecial #63;//Method java/lang/StringBuilder." ng/String;)V 26: aload_1 27: aload_2 28: if_acmpne 35 31: iconst_1 32:goto 36 35: iconst_0 36: invokevirtual #66;//Method java/lang/StringBuilder.append:(Z)Ljava/la ng/StringBuilder; 39: invokevirtual #70;//Method java/lang/StringBuilder.toString:()Ljava/l ang/String; 42: invokevirtual #74;//Method java/io/PrintStream.println:(Ljava/lang/St ring;)V 45:return
} |
分析
javap是Java自带的一个工具,可以反编译,也可以查看Java编译器生成的字节码(上面代码只使用了javap -c DataType),是分析代码的一个好工具,具体怎么使用请Google一下
先看一下m4,为什么运行结果中出现了“true”呢,true说明a、b是同一个对象。
但a对象是调用Integer.valueOf()生成的,b是通过自动装箱生成的对象,为什么会是同一个对象呢?再看一下字节码吧,毕竟Java程序是依靠虚拟机运行字节码实现的。
m41这个方法只适用了一次valueOf(),但字节码中出现了两次,说明自动装箱时也调用了valueOf()。
下面是valueOf()具体实现
/** * Returns a Integer instance representing the specified * int value. * If a new Integer instance is not required, this method * should generally be used in preference to the constructor * {@link #Integer(int)}, as this method is likely to yield * significantly better space and time performance by caching * frequently requested values. * * @param i an * @return a Integer instance representing i. * @since 1.5 */ publicstaticInteger valueOf(inti) { finalintoffset =128; if(i >= -128&& i <=127) {// must cache returnIntegerCache.cache[i + offset]; } returnnewInteger(i); } |
在【-128,127】之间的数字,valueOf返回的是缓存中的对象,所以两次调用返回的是同一个对象。
-
下一个: java实现的冒泡排序算法示例
相关文章
- mybatis基本实例详解 08-03
- C语言 makefile学习及实现实例 08-01
- ps玻璃杯子制作实例 07-26
- Python编程之event对象的用法实例分析 07-20
- 详解Java CountDownLatch完成异步回调实例 07-18
- 数码单反怎么摄影 数码单反实例教程 07-13