如何理解Java中的自动拆箱和自动装箱?
如何理解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,那么问题来了,既然是库存,那么势必就要用到加减乘除之类的运算,所以就需要先转换成 数值类型(intlongfloat等)来运算,我们看一下通过包装类是如何快速转换的「intlongfloat」:
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、 落实自动装箱、拆箱
看完了包装类型的便捷性后,我们再来落实到自动装箱、自动拆箱上...
怎么就自动装箱,自动拆箱了呢?
上一段代码,看看哪是自动装箱跟自动拆箱:
// 自动装箱
- Integer a = 100;
// 自动拆箱 - 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() 方法实现拆箱,接下来我们再结合几行代码重新回顾一下:
- Integer a = new Integer(100);
- Integer b = 100;
- 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()方法实现拆箱。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Python3 使用pli优化图片大小,相机或手机拍图片根据exif旋转、纠正方向
首先安装 pip install pillow 如果报错,请根据报错的信息去搜索一下,一般都能得到解决,未找到请升级pip python -m pip install --upgrade pip 或者 pip install --upgrade pip 那么写个方法 from PIL import Image,ExifTags #定义保存图片都路径 def get_outfile(infile, outfile): if outfile: return outfile dir, suffix = os.path.splitext(infile) outfile = '{}-cover{}'.format(dir, suffix) return outfile #缩小图片大小,保持原始宽高 def compress_image(infile, outfile='', kb=3200, step=5, quality=80): o_size = os.path.getsize(infile) / 1024 if o_size <= kb: return False outfile =...
- 下一篇
Java高级特性之集合
Java高级特性之集合 Java集合框架 一、Java集合框架概述 1、数组与集合的区别: 1)数组长度不可变化而且无法保存具有映射关系的数据;集合类用于保存数量不确定的数据,以及保存具有映射关系的数据。 2)数组元素既可以是基本类型的值,也可以是对象;集合只能保存对象。 2、Java集合类主要由两个根接口Collection和Map派生出来的,Collection派生出了三个子接口:List、Set、Queue(Java5新增的队列),因此Java集合大致也可分成List(有序、可重复集合、可直接根据元素的索引来访问)、Set(无序、不可重复集合、只能根据元素本身来访问)、Queue(队列集合)、Map(存储key-value对的集合,可根据元素的key来访问value)这四种。 二、Java集合常见接口及实现类 1、Collection接口常见方法 2、List集合 实现List接口的集合主要有:ArrayList、LinkedList、Vector、Stack。 它们都可以容纳所有类型的对象,包括 null,允许重复,并且都保证元素的存储顺序。(可重复,有顺序) 1)ArrayL...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- Hadoop3单机部署,实现最简伪集群
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装