如何理解Java中的自动拆箱和自动装箱?
小伟刚毕业时面的第一家公司就被面试官给问住了,记忆尤深啊...
如何理解Java中的自动拆箱和自动装箱?
自动拆箱?自动装箱?什么鬼,听都没听过啊,这...这..知识盲区...
回到家后小伟赶紧查资料,我透,这不就是问基本类型跟封装类型吗,面试官整啥名词呢...
别问结果,问就是没过。
1、 什么是自动装箱,自动拆箱
定义:基本数据类型和包装类之间可以自动地相互转换
理解:装箱就是自动将基本数据类型转换为封装类型,拆箱就是自动将封装类型转换为基本数据类型。
我们知道,Java中提供了四大类基本数据类型,分别是:整数、浮点数、字符型和布尔型,其中:
- 整数包含:byte、int、short、long
- 浮点数包含:float、double
- 字符类型:char
- 布尔类型:boolean
基本数据类型相信大家一定很熟悉了吧,来来来,说说他们的取值范围~
| 数据类型 | 取值范围 |
|---|---|
| byte | -128 ~ 127 |
| short | -32786 ~ 32767 |
| int | -4294967296 ~ 4294967295 |
| long | -2^64^ ~ 2^64^ -1 |
| float | 3.4e-038 ~ 3.4e+038 |
| double | 1.7e-308 ~ 1.7e+308 |
| char | \u0000 ~ \uffff |
| boolean | true 、false |
日常开发中,靠这些基本数据类型几乎能够满足我们的需求,但是基本类型终究不是对象,往重了说不满足面向对象的开发思想,往轻了说就是使用不方便。怎么讲?例如做一些数据类型转换,获取int数据类型的取值范围等等。
我们知道,类的优点在于它可以定义成员变量、成员方法,提供丰富便利的功能,因此Java在JDK1.0的时候就设计了基本数据类型的包装类,而在JDK1.5中引入了新特性:自动装箱和拆箱。
我们来看一下基本类型跟封装类型之间的对应关系:
| 数据类型 | 封装类 |
|---|---|
| byte | Byte |
| short | Short |
| int | Integer |
| long | Long |
| float | Float |
| double | Double |
| char | Character |
| boolean | Boolean |
2、 使用包装类型后的便捷
我们以上边提到的数据类型转换为例,看看使用包装类型后的便捷性。
小伟在数据库中存放商品库存用的是 varchar 类型来存储的,所以在代码中的实体与之对应的是 String,那么问题来了,既然是库存,那么势必就要用到加减乘除之类的运算,所以就需要先转换成 数值类型(int\long\float等)来运算,我们看一下通过包装类是如何快速转换的「int\long\float」:
public class Test {
public static void main(String[] args) {
// 数据库中的商品数量 number
String number = "666";
// 借助封装了 Integer 转换为 int
int intVal = Integer.valueOf(number);
// 借助封装了 Float 转换为 float
float floatVal = Float.valueOf(number);
// 借助封装了 Long 转换为 long
long longVal = Long.valueOf(number);
// 依次输出三个值的内容
System.out.println("int="+intVal);
System.out.println("floatVal="+floatVal);
System.out.println("longVal="+longVal);
}
}
3、 落实自动装箱、拆箱
看完了包装类型的便捷性后,我们再来落实到自动装箱、自动拆箱上...
怎么就自动装箱,自动拆箱了呢?
上一段代码,看看哪是自动装箱跟自动拆箱:
// 自动装箱
1. Integer a = 100;
// 自动拆箱
2. int b = a;
自动装箱,相当于Java编译器替我们执行了 Integer.valueOf(XXX);
自动拆箱,相当于Java编译器替我们执行了Integer.intValue(XXX);
我们证实一下,首先通过 javac 编译得到 class 文件,接着反编译看看:
指令为:javap -c class文件名,得到下图所示:

看完编译器替我们做的,接下来我们再通过源码看看,首先是自动装箱 valueOf() 方法:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
我们可以看到,首先是if方法, 对传入的int 数值进行判断,如果 i >= -128 且i <= 127 那么就会从IntegerCache缓存中获取指定数字的封装类,如果不存在则 new 出一个新的封装类,关于 IntegerCache ,其内部实现了一个Integer的静态常量数组,在类加载的时候,执行static静态块进行初始化-128~127之间的Integer对象,存放到cache数组中,cache属于常量,存放在java的方法区中,对方法区不太了解的小伙伴可以先留空,后面我会单独水一篇的~
额外补充一下:上边我们只看了Integer封装类的自动装箱方法,从方法中我们了解了在
-128~127之间使用了缓存,那么是不是意味着别的封装类也是这样呢?其实不是的,首先Integer使用缓存原因是该区间会被经常使用到,且数量个数比较确定,就256个值,所以为了提高效率,防止每次自动装箱都创建一次对象实例,然后就你懂得~,而double、float浮点型是没有使用缓存的,因为小数点的原因,所以在这个区间范围内个数是比较泛的,即不适合缓存,没有意义。
我们通过一段代码看看这个缓存的效果吧:
public class Test2 {
public static void main(String[] args) {
Integer a = 100;
Integer b = 100;
Integer c = 200;
Integer d = 200;
System.out.println(a==b); // 打印true
System.out.println(a==b); // 打印false
}
}
接着再来看自动拆箱 intValue() 方法:
private final int value;
public int intValue() {
return value;
}
这个方法就比较简单了,调用时直接返回了基本数据类型的 value 值。
至此我们看完了自动装箱、自动拆箱,以Integer为例我们知道了使用 valueOf() 方法实现装箱,使用 intValue() 方法实现拆箱,接下来我们再结合几行代码重新回顾一下:
1. Integer a = new Integer(100);
2. Integer b = 100;
3. b+=100;
第一行代码:new 了一个 Integer 对象实例,将 int 类型的数据传入包装成了 Integer 类型。
第二行代码:首先我们知道 100 是 int 类型的,但是等待复制的 b 是 Integer 类型,此时就用到了自动装箱,
b = Integer.valueOf(100),将100包装成包装类了「通过反编译验证」第三行代码:用到了自动装箱+自动拆箱,
b = b + 100 = Integer.intValye(b) + 100此时计算结果得到的应该是 int 类型的 b,但是 b 又被限定了是 Integer 类型,所以就又要用到Integet.valueOf()自动装箱。
4、 上才艺
才艺一:如何理解Java中的自动拆箱和自动装箱?
答:自动装箱就是将基本数据类型自动转换为封装类型,自动拆箱是将封装类型自动转换为基本数据类型。
才艺二:能说一下是通过哪些方法实现自动拆箱、装箱的吗?
答:以Integer为例,使用Integer.valueOf()方法实现装箱,使用Integer.intValue()方法实现拆箱。

推荐阅读:
如何理解Java中的自动拆箱和自动装箱?的更多相关文章
- JavaStudy——Java之自动拆箱与自动装箱
java基本类型介绍 java中,基本数据类型一共有8种,详细信息如下表: 类型 大小 范围 默认值 byte 8 -128 - 127 0 short 16 -32768 - 32768 0 int ...
- Java进阶之自动拆箱与自动装箱
序. java基本类型介绍 java中,基本数据类型一共有8种,详细信息如下表: 类型 大小 范围 默认值 byte 8 -128 - 127 0 short 16 -32768 - 32768 0 ...
- 享元模式(FlyWeight Pattern)及其在java自动拆箱、自动装箱中的运用
本文主要从三个方面着手,第一:简要介绍享元模式.第二:享元模式在基本类型封装类中的运用以Integer为例进行阐述.第三:根据第一.第二的介绍,进而推出java是如何实现自动拆箱与装箱的. 第一:简要 ...
- Java语法糖2:自动装箱和自动拆箱
前言 一开始想学学自动拆箱和自动装箱是被这个名字吸引到,听上去好像很高端的样子,其实自动拆箱.自动装箱是很简单的内容. 自动拆箱和自动装箱 Java为每种基本数据类型都提供了对应的包装器类型.举个例子 ...
- 转!!Java学习之自动装箱和自动拆箱源码分析
自动装箱(boxing)和自动拆箱(unboxing) 首先了解下Java的四类八种基本数据类型 基本类型 占用空间(Byte) 表示范围 包装器类型 boolean 1/8 true|fal ...
- Java学习之自动装箱和自动拆箱源码分析
自动装箱(boxing)和自动拆箱(unboxing) 首先了解下Java的四类八种基本数据类型 基本类型 占用空间(Byte) 表示范围 包装器类型 boolean 1/8 true|false ...
- Java中的自动拆箱装箱(Autoboxing&Unboxing)
一.基本类型打包器 1.基本类型:long.int.double.float.boolean 2.类类型:Long.Integer.Double.Float.Boolean 区别:基本类型效率更高,类 ...
- 别说你不知道java中的包装类,wrapper type,以及容易在自动拆箱中出现的问题
很多时候,会有人问你,你知道什么是包装类吗? 或者高端一点问你你知道,wrapper type,是什么吗? 然后你就懵逼了,学了java很多时候都不知道这是啥. 其实问你的人,可能只是想问你,java ...
- 深入理解Java中的装箱与拆箱
一.Java数据类型 1.在说装箱与拆箱之前,先说一下Java的基本数据类型,Java从数据类型上可以划分为值类型与引用类型,值类型是四类八种,分别是: 整数型:byte̵,short̵,int̵,l ...
随机推荐
- caffe学习笔记(1)安装 - Ubuntu 15.04
官方安装手册 备注:使用系统 - Ubuntu 15.04 64位操作系统(若系统位于虚拟机上,在安装CUDA后,Ubuntu将无法进入图形界面) /************************* ...
- 图论--最长路--基于SPFA的调整模板
#include<iostream> #include<queue> #include<algorithm> #include<set> #includ ...
- codeforce 227E 矩阵快速幂求斐波那契+N个连续数求最大公约数+斐波那契数列的性质
E. Anniversary time limit per test2 seconds memory limit per test256 megabytes inputstandard input o ...
- 2019 ICPC 银川网络赛 D. Take Your Seat (疯子坐飞机问题)
Duha decided to have a trip to Singapore by plane. The airplane had nn seats numbered from 11 to nn, ...
- docker批量删除本地镜像和容器
长时间运行docker,每次只用docker kill去停止容器,但是从没删除过本地镜像,导致有上百个镜像在占用内存. 1.批量停止容器 docker container stop $(docker ...
- 如何使用简单 PHP 对象 POPO (Plain old PHP Object) 来优化你的代码
如果您熟悉 Java,可能您已经知道 POJO (普通 Java 类). 因为 POJO 这个词最早是由 Martin Fowler.Rebecca Parsons 和 Josh MacKenzie ...
- Mysql数据库分页查询
为什么使用分页查询: 数据量比较大时,如果全部查询,展示刚给用户,数据量太大,用户难以接受.并且数据量大,查询慢.如果此时将大量的数据读取到java内存中,可能会存储崩溃. 分页查询的方式: 1.全部 ...
- [js进阶1]-数据类型
基本数据类型 js 总的有7中数据类型,包括基本类型和引用类型 基本类型 6 种 number boolean string null undefiend symbol 前5种类型统称为原始类型 sy ...
- 【Hadoop离线基础总结】oozie调度shell脚本
目录 1.解压官方提供的调度案例 2.创建工作目录 3.拷贝任务模板到工作目录当中去 4.随意准备一个shell脚本 5.修改模板下的配置文件 6.上传调度任务到hdfs上面去 7.执行调度任务 1. ...
- 设计模式之GOF23适配器模式
结构型模式 核心作用:是从程序的结构上实现松耦合,从而可以扩大整体的 类结构,用来解决更大的问题 适配器模式adapter 实际生活中的例子:转换器 适配器的两种方式: 1,类适配器(继承) /**需 ...