Java装箱和拆箱的基本概念及使用
Java装箱和拆箱的基本概念及使用
要理解装箱和拆箱的概念,就要理解Java数据类型
装箱:把基本类型用它们相应的引用类型包装起来,使其具有对象的性质。int包装成Integer、float包装成Float
拆箱:和装箱相反,将引用类型的对象简化成值类型的数据
Integer a = 100; 这是自动装箱 (编译器调用的是static Integer valueOf(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."< init >":(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."< init >":(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."< init >":(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."< init >":(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."<init>":(I)V
9: astore_1
10: new #44; //class java/lang/Integer
13: dup
14: bipush 100
16: invokespecial #46; //Method java/lang/Integer."<init>":(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."<init>":(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."<init>":(I)V
10: astore_1
11: new #44; //class java/lang/Integer
14: dup
15: sipush 128
18: invokespecial #46; //Method java/lang/Integer."<init>":(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."<init>":(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; //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."<init>":(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."<init>":(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."<init>":(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."<init>":(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 <tt>Integer</tt> instance representing the specified * <tt>int</tt> value. * If a new <tt>Integer</tt> 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 <code>int</code> value. * @return a <tt>Integer</tt> instance representing <tt>i</tt>. * @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返回的是缓存中的对象,所以两次调用返回的是同一个对象。
Java装箱和拆箱的基本概念及使用的更多相关文章
- 1.1 JAVA装箱和拆箱以及Java Number & Math&Character 类
JAVA装箱和拆箱 从Java SE5开始就提供了自动装箱的特性,如果要生成一个数值为10的Integer对象,只需要这样就可以了.原文链接: http://www.cnblogs.com/dolph ...
- Java 装箱和拆箱
1.装箱机制 基础类型引用到其包装类型,这样就可以调用其各种方法. 例如,我们声明: Integer a = 1; 其在编译过程中会自动解释成: Integer a = Integer.valueOf ...
- java装箱跟拆箱解析
/** * 在jdk1.5之后,java为基本数据类型到对应的应用数据类型提供了自动拆箱装箱操作 * 不管是自动拆箱还是自动装箱都是应用数据类型有的方法,基本数据类型是没有任何方法可调用的 *从概念上 ...
- JAVA——装箱和拆箱
Java 将某些基本数据类型自动转换为包装类型的过程称为装箱,相反自动将包装类型转换为基本数据类型的过程称为拆箱. Integer integer_1=1; //装箱 int i=integer_1; ...
- Java 装箱、拆箱 包装器
先说java的基本数据类型.java基本数据类型:byte.short.int.long.float.double.char.boolean 基本数据类型的自动装箱(autoboxing).拆箱(un ...
- Java装箱和拆箱
https://www.cnblogs.com/dolphin0520/p/3780005.html http://mxdxm.iteye.com/blog/2028196 装箱过程是通过调用包装器的 ...
- java和c#中的装箱和拆箱操作
c#装箱和拆箱 装箱:整体上来说,装箱是将值类型转换成引用类型,比如将Vector3转换成Object类型. 具体而言: 1)在托管堆中为值类型分配内存.除了原始的数值以外还应该有指向该数值的引用. ...
- Java暗箱操作之自动装箱与拆箱
我以前在写Android项目的时候,估计写得最多最熟练的几句话就是: List<Integer> list = new ArrayList<Integer>(); list.a ...
- 深入剖析Java中的装箱和拆箱
深入剖析Java中的装箱和拆箱 自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就来一些看一下装箱和拆箱中的若干问题.本文先讲述装箱和拆箱最基本的东西,再来看一下面试笔试中经常遇到的与装箱 ...
随机推荐
- MySQL 核心三剑客 —— 索引、锁、事务
一.常见存储引擎 1.1 InnoDB InnoDB 是 MySQL 5.5 之后默认的存储引擎,它具有高可靠.高性能的特点,主要具备以下优势: DML 操作完全遵循 ACID 模型,支持事务,支持崩 ...
- idea2020注册码永久激活(激活到2100年)
首先有图有真相: 资源链接: 链接:https://pan.baidu.com/s/1DPIllnyhc7H4qL2yQb0OvQ 提取码:lbjx 第一步:将bin目录下的三个文件拷贝到IDEA安装 ...
- appium获取toast和操作webview实例
从testerhome上看到很多测试同学分享了toast的获取方式,其中大部分是java版本的,但也有个python版本的:Appium1.7.2 android toast 消息测试 Appium获 ...
- 「Luogu P2508」[HAOI2008]圆上的整点 解题报告
题面 给定圆的半径,求圆上整点数 这是一道很Nice的数学题!超爱!好吧,由于这道题,我去Study了一下复数(complex number)复杂的数 真棒!!! 有兴趣的戳这里!!!\(\huge ...
- python版飞机大战代码简易版
# -*- coding:utf-8 -*- import pygame import sys from pygame.locals import * from pygame.font import ...
- Java散点
1.在Java中,所有需要保存在常量池中的数据,长度最大不能超过65535,这当然也包括字符串的定义
- 升级添加到现有iOS Xcode项目的Flutter
如果你在2019年8月之前将Flutter添加到现有iOS项目,本文值得你一看. 在2019年7月30日,合并合并请求flutter / flutter#36793之前Flutter 1.8.4-pr ...
- JS获取时间戳的几种方法与区别
var today = new Date() Date.now()) Date.parse(today) today.valueOf()) today.getTime() 可以看出,第二种是精确到秒的 ...
- C#.Net ComboBox控件设置DropDownList之后背景颜色问题,以及发现的微软的一个BUG
先说背景颜色问题怎么处理. C#.Net WinForm中如果设置ComboBox的DropDownStyle为DropDownList,控件背景色会变成灰色,并且这个时候ComboBox控件的Bac ...
- floj 2264
2.公路建设(highway.c/cpp/pas) 在滨海市一共有n 个城市,编号依次为1到n,它们之间计划修建m条双向道路,其中修建第i条道路的费用为ci. 海霸王作为滨海市公路建设项目的总工程师, ...