自动装箱、拆箱了解多少?
写在前面
Java 为我们提供了 8 种基本数据类型,为什么还需要提供各自的包装类型呢?您可能会觉得这个问题问的很奇怪,但是我觉得还是值的思考的。
因为 Java 是一门面向对象的语言,基本数据类型并不具备对象的性质。而包装类型则是在基本类型的基础上,添加了属性和方法,从而成为了对象。试想,一个 int 类型怎么添加到 List 集合中?
如何理解Java中的自动拆箱和自动装箱?
自动拆箱?自动装箱?什么鬼,听都没听过啊,这…这…知识盲区…
回到家后赶紧查资料,我透,这不就是问基本类型跟封装类型吗,面试官整啥名词呢…
别问结果,问就是没过。
自动装箱、拆箱
定义: 基本数据类型和包装类之间可以自动地相互转换
理解: 装箱就是自动将基本数据类型转换为封装类型,拆箱就是自动将封装类型转换为基本数据类型。
我们来看个例子:
Integer number = 10; // 自动装箱
int count = number; // 自动拆箱
我们知道,Java 中提供了四大类基本数据类型,分别是:整数、浮点数、字符型和布尔型,其中:
- 整数包含:byte、int、short、long
- 浮点数包含:float、double
- 字符类型:char
- 布尔类型:boolean
基本数据类型相信大家一定很熟悉了吧,来来来,说说他们的取值范围~
数据类型 | 取值范围 |
---|---|
byte | -128 ~ 127 |
short | -32786 ~ 32767 |
int | -4294967296 ~ 4294967295 |
long | -264 ~ 264 -1 |
float | 3.4e-038 ~ 3.4e+038 |
dubbo | 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 |
何时会发生拆箱、装箱?
自动装箱和拆箱在 Java 中很常见,比如我们有一个方法,接受一个对象类型的参数,如果我们传递一个原始类型值,那么 Java 会自动将这个原始类型值转换成与之对应的对象。最经典的一个场景就是当我们向 ArrayList 这样的容器中增加原始类型数据时或者是创建一个参数化的类,比如下面的 ThreadLocal。
ArrayList<Integer> intList = new ArrayList<Integer>();
intList.add(1); // 装箱
intList.add(2); // 装箱ThreadLocal<Integer> intLocal = new ThreadLocal<Integer>();
intLocal.set(4); // 装箱int number = intList.get(0); // 拆箱
int local = intLocal.get(); // 拆箱
上面的示例我们介绍了自动装箱和拆箱以及它们何时发生,我们知道了自动装箱主要发生在两种情况,一种是赋值时,另一种是在方法调用的时候。
赋值时
这是最常见的一种情况,在 Java 1.5 以前我们需要手动地进行转换才行,而现在所有的转换都是由编译器来完成。
// before autoboxing
Integer iObject = Integer.valueOf(3);
int iPrimitive = iObject.intValue()//after java5
Integer iObject = 3; // autobxing - primitive to wrapper conversion
int iPrimitive = iObject; // unboxing - object to primitive conversion
方法调用时
这是另一个常用的情况,当我们在方法调用时,我们可以传入原始数据值或者对象,同样编译器会帮我们进行转换。
public static Integer show(Integer iParam){System.out.println("autoboxing example - method invocation i: " + iParam);return iParam;
}// autoboxing and unboxing in method invocation
show(3); // autoboxing
int result = show(3); // unboxing because return type of method is Integer
show() 方法接受 Integer 对象作为参数,当调用 show(3) 时,会将 int 值转换成对应的 Integer 对象,这就是所谓的自动装箱,show() 方法返回 Integer 对象,而 int result = show(3); 中 result 为 int 类型,所以这时候发生自动拆箱操作,将 show() 方法返回的 Integer 对象转换成 int 值。
自动装拆箱的弊端
自动装箱有一个问题,那就是在一个循环中进行自动装箱操作的情况,如下面的例子就会创建多余的对象,影响程序的性能。
Integer sum = 0;
for(int i=1000; i<5000; i++){sum += i;
}
上面的代码 sum += i 可以看成 sum = sum + i,但是 + 这个操作符不适用于 Integer 对象,首先 sum 进行自动拆箱操作,然后进行数值相加操作,最后发生自动装箱操作转换成 Integer 对象。其内部变化如下:
int result = sum.intValue() + i;
Integer sum = new Integer(result);
由于我们这里声明的 sum 为 Integer 类型,在上面的循环中会创建将近 4000 个无用的 Integer 对象,在这样庞大的循环中,会降低程序的性能并且加重了垃圾回收的工作量。因此在我们编程时,需要注意到这一点,正确地声明变量类型,避免因为自动装箱引起的性能问题。
总结
因为自动装箱会隐式地创建对象,像前面提到的那样,如果在一个循环体中,会创建无用的中间对象,这样会增加 GC 压力,降低程序的性能。所以在写循环时一定要注意,避免引入不必要的自动装箱操作。
总的来说,自动装箱和拆箱着实为开发者带来了很大的方便,但是在使用时也是需要格外留意,避免引起出现文章提到的问题。
自动装箱、拆箱了解多少?相关推荐
- Java自动装箱/拆箱 - Java那些事儿
昨天Java基本数据类型和引用类型一文中漏了几张图,已经补上,需要的自己回头去看,本系列文章首发于公众号:saysayJava. 在让人疑惑的Java代码 - Java那些事儿 一文中我们说到编译器自 ...
- Java基础笔记 – 增强的for循环For each循环 自动装箱拆箱 可变参数
1.For each循环:1.1.语法:1.2.For each循环的使用:1.3.嵌套For each循环:1.4.三种循环遍历集合的列举:1.5.增强的for循环的缺点:2.自动装箱/拆箱(Aut ...
- Java八种基本数据类型的大小,以及封装类,自动装箱/拆箱的用法?
参考:http://blog.csdn.net/mazhimazh/article/details/16799925 1. Java八种基本数据类型的大小,以及封装类,自动装箱/拆箱的用法? 原始类型 ...
- java自动装箱拆箱原理
java自动装箱拆箱原理 看了很多博主都没写原理,只是浅显地说了自动装箱拆箱的含义,我就把这个必须知道的知识写一下吧 1.自动装箱 以int -> Integer为例,Integer integ ...
- Java 8 自动装箱拆箱效率影响测试
Java 8 自动装箱拆箱效率影响测试 测试完毕之后的结论: 1. 装箱发生 232−12^{32-1}232−1 次的时候影响时间大概为10秒 2. 拆箱发生 232−12^{32-1}23 ...
- java自动装箱拆箱深入剖析
这个是jdk1.5以后才引入的新的内容,作为秉承发表是最好的记忆,毅然决定还是用一篇博客来代替我的记忆: java语言规范中说道:在许多情况下包装与解包装是由编译器自行完成的(在这种情况下包装成为装 ...
- java 自动拆箱_Java中的自动装箱拆箱
Java中的自动装箱拆箱 一.自动装箱与自动拆箱 自动装箱就是将基本数据类型转换为包装类类型,自动拆箱就是将包装类类型转换为基本数据类型. 1 //自动装箱 2 Integer total = 90; ...
- Java自动装箱/拆箱
自动装箱和自动拆箱 那么Java中有八大基本数据类型,byte.char.short.int.long.double.float.boolean.而它们有对应的包装类 Byte.Character.S ...
- BeanShell自动装箱拆箱
"装箱"和"拆箱"是用来描述自动包装一个原始类型到一个包装类以及在必要时解开包装回到原始类型的术语.装箱是 Java 的特性(SDK 1.5)之一,且 Bean ...
- java基础--06(自动装箱拆箱)
目录 1.自动装箱,自动拆箱 1.自动装箱,自动拆箱 装箱就是自动将基本数据类型转换为包装器类型:拆箱就是 自动将包装器类型转换为基本数据类型. java的数据类型: 自动装箱: 最主要的就是Inte ...
最新文章
- 可打开可关闭的选项卡,单纯无污染,改改样式就能用
- 编译原理预测分析法c语言,编译原理预测分析法C语言的实验报告.doc
- 美国进步派民主党众议员寻求大幅扩大拜登第二项支出计划规模
- JavaWeb那些事儿(一)--为什么做java的web开发使用struts2,springMVC和spring这样的框架
- STM32 HAL SPI读取MPU6500的设备ID异常
- 白话数字签名(1)——基本原理
- DB2 SQLCODE常见错误代码
- CRMEB 【Java版】单商户商城系统v1.4.1
- 深入理解 Spring 事务原理
- 如何用python计算年龄_python根据出生日期计算年龄的代码
- 雷达原理-运动目标检测与测速
- 科技风杂志科技风杂志社科技风编辑部2022年第16期目录
- 数据库 - 交集、并集和补集
- 《邪不压正》好不好看?大数据分析告诉你
- 免费好用的APP你值得一试
- L1 L2正则化和优化器的weight_decay参数
- 旷野徒奔-Java底层篇(1.4)
- 计算机网络安全ipc默认共享,IPC$、ADMIN$、C$、D$都是什么?如何关闭取消删除Windows默认共享...
- 人生的悲哀莫过于:求而不得,舍而不能,得而不惜
- 52. 常用的数学工具类9-大乐透号码生成器
热门文章
- QoS配置与管理实战——疑惑再探讨
- c语言中因式分解的题目,因式分解练习题加答案解析-200道.doc
- 2018手机号码正则表达式
- iframe 父页面全屏同时子页面 viewer轮播插件全屏放大 Uncaught DOMException: Blocked a frame with origin null from acce
- 成功职业经理人的34个好习惯
- Elasticsearch集群环境搭建
- Java 遍历List的4种方式
- 桂林航天工业学院计算机实验报告,桂林航天工业学院电子工程系程控交换实验报告详解.doc...
- 新时达电梯服务器显示外呼错,新时达电梯系统常见故障分析
- 员工满意度调查表第一部分,对企业管理制度的调查表10题