Java 装箱与拆箱详解及实例代码

网友投稿 198 2023-06-19


Java 装箱与拆箱详解及实例代码

java 装箱与拆箱详解

前言:

要理解装箱和拆箱的概念,就要理解Java数据类型

装箱:把基本类型用它们相应的引用类型包装起来,使其具有对象的性质。int包装成Integer、float包装成Float

拆箱:和装箱相反,将引用类型的对象简化成值类型的数据

Integer a = 100; 这是自动装箱 (编译器调用的是static Integer vUQMlEalueOf(int i))

int b = new Integer(100); 这是自动拆箱

看下面一段代码

m1

public class DataType {

public static void main(String args[]) {

DataType dt = new DataType();

dt.m11();

dt.m12();

}

public void m11() {

Integer a = new Integer(100);

Integer b = 100;

System.out.println("m11 result " + (a == b));

}

public void m12() {

Integer a = new Integer(128);

Integer b = 128;

System.out.println("m12 result " + (a == b));

}

}

打印结果是什么?

m11 result false

m12 result false

“==”比较的是地址,而a和b两个对象的地址不同,即是两个对象,所以都是false

通过javap解析字节码,内容如下

public void m11();

Code:

0: new #44; //class java/lang/Integer

3: dup

4: bipush 100

6: invokespecial #46; //Method java/lang/Integer."":(I)V

9: astore_1

10: bipush 100

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."":(Ljava/la

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

public void m12();

Code:

0: new #44; //class java/lang/Integer

3: dup

4: sipush 128

7: invokespecial #46; //Method java/lang/Integer."":(I)V

10: astore_1

11: sipush 128

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."":(Ljava/la

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

public class DataType {

public static void main(String args[]) {

DataType dt = new DataType();

dt.m21();

dt.m22();

}

public void m21() {

Integer a = new Integer(100);

Integer b = new Integer(100);

System.out.println("m21 result " + (a == b));

}

public void m22() {

Integer a = new Integer(128);

Integer b = new Integer(128);

System.out.println("m22 result " + (a == b));

}

}

打印结果是

m21 result false

m22 result false

a和b仍是两个对象

javap解析内容

public void m21();

Code:

0: new #44; //class java/lang/Integer

3: dup

4: bipush 100

6: invokespecial #46; //Method java/lang/Integer."":(I)V

9: astore_1

10: new #44; //class java/lang/Integer

13: dup

14: bipush 100

16: invokespecial #46; //Method java/lang/Integer."":(I)V

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."":(Ljava/la

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

public void m22();

Code:

0: new #44; //class java/lang/Integer

3: dup

4: sipush 128

7: invokespecial #46; //Method java/lang/Integer."":(I)V

10: astore_1

11: new #44; //class java/lang/Integer

14: dup

15: sipush 128

18: invokespecial #46; //Method java/lang/Integer."":(I)V

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."":(Ljava/la

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

public class DataType {

public static void main(String args[]) {

DataType dt = new DataType();

dt.m31();

dt.m32();

}

public void m31() {

Integer a = 100;

Integer b = 100;

System.out.println("m31 result " + (a == b));

}

public void m32() {

Integer a = 128;

Integer b = 128;

System.out.println("m32 result " + (a == b));

}

}

打印结果

m31 result true

m32 result false

为什么有第一个是true,第二个是false呢?观察javap解析的数据

javap解析内容

public void m31();

Code:

0: bipush 100

2: invokestatic #49; //Method java/lang/Integer.valueOf:(I)Ljava/lang/In

teger;

5: astore_1

6: bipush 100

8: invokestatic #49;http:// //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."":(Ljava/la

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

public void m32();

Code:

0: sipush 128

3: invokestatic #49; //Method java/lang/Integer.valueOf:(I)Ljava/lang/In

teger;

6: astore_1

7: sipush 128

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."":(Ljava/la

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

public class DataType {

public static void main(String args[]) {

DataType dt = new DataType();

dt.m41();

dt.m42();

}

public void m41() {

Integer a = Integer.valueOf(100);

Integer b = 100;

System.out.println("m41 result " + (a == b));

}

public void m42() {

Integer a = Integer.valueOf(128);

Integer b = 128;

System.out.println("m42 result " + (a == b));

}

}

打印结果

m41 result true

m42 result false

javap解析内容

public void m41();

Code:

0: bipush 100

2: invokestatic #49; //Method java/lang/Integer.valueOf:(I)Ljava/lang/In

teger;

5: astore_1

6: bipush 100

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."":(Ljava/la

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

public void m42();

Code:

0: sipush 128

3: invokestatic #49; //Method java/lang/Integer.valueOf:(I)Ljava/lang/In

teger;

6: astore_1

7: sipush 128

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."":(Ljava/la

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 int value.

* @return a Integer instance representing i.

* @since 1.5

*/

public static Integer valueOf(int i) {

final int offset = 128;

if (i >= -128 && i <= 127) { // must cache

return IntegerCache.cache[i + offset];

}

return new Integer(i);

}

在【-128,127】之间的数字,valueOf返回的是缓存中的对象,所以两次调用返回的是同一个对象。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:bootstrap table分页模板和获取表中的ID方法
下一篇:微信端开发
相关文章

 发表评论

暂时没有评论,来抢沙发吧~