Java学习记录--自动拆箱与装箱
时间:2022-06-11
本文章向大家介绍Java学习记录--自动拆箱与装箱,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
先提问题
- 什么是自动拆箱与装箱?
- 什么情况下会自动拆箱与装箱?
- 对性能的影响?
- 使用建议
什么是自动拆箱与装箱?
自动拆箱与装箱是Java5引入的新特性,目的是解决基本类型与包装类型之间切换的麻烦. 装箱
Integer num = 1;
编译之后的代码如下,此时Integer.valueOf()
把基本类型转换为包装类型叫装箱.
Integer num = Integer.valueOf((int)1);
拆箱
// 装箱
Integer num = 1;
Integer num2 = 2;
// 先拆再装
Integer num3 = num + num2;
编译之后代码,调用num.intValue()
的过程叫做拆箱.对于+
操作符,其只支持基本类型,因此必然会先拆箱,最后结果又是Integer
包装类型,因此赋值时发生了装箱.
Integer num = Integer.valueOf((int)1);
Integer num2 = Integer.valueOf((int)2);
Integer num3 = Integer.valueOf((int)(num.intValue() + num2.intValue()));
简单来说,基本类型与包装类型在某些操作符的作用下,发生包装类型调用valueOf()
方法的过程叫做装箱,基本类型调用xxValue()
的过程叫做拆箱.
什么情况下会自动拆箱与装箱?
拆箱
- 只支持基本类型的操作符,如+-*/
- 包装类型与基本类型共同进行多元操作.例如包装类型->基本类型赋值
double num7 = new Double(1)
.
装箱
- 包装类型与基本类型共同进行多元操作.例如基本类型->包装类型赋值
double double1 =10D
举例:
// 正常赋值
double double1 =10D;
//装箱 基本类型 -> 包装类型
Double double2 =10D;
// 装箱 基本类型 -> 包装类型
Double double3 =10D;
// double2拆箱 +号只支持基本类型
double double4 = double1 + double2;
// double2,double3拆箱,double5装箱 +号只支持基本类型,基本类型 -> 包装类型
Double double5 = (double2 + double3);
==的特殊性
==
操作符既支持基本类型又支持包装类型(引用类型),那么某些地方必然会有歧义,这类操作符有一个原则,当有基本类型时以基本类型为主.
double double1 =10D;
Double double2 =10D;
Double double3 =10D;
// double2拆箱,因此比较值
System.out.println(double1 == double2); //true
// 包装类比较,直接比较引用地址.
System.out.println(double2 == double3); //false
对性能的影响?
装箱与拆箱本质是创建对象(valueOf)与调用对象方法(xxValue),没有多小性能消耗.但是在循环中也可能成为拖慢系统的最后一根稻草.如下面代码再一次循环中会有两次拆箱,一次装箱的消耗,不考虑缓存的影响循环多少次就创建了多少个Integer
对象,虽然执行仍然会很快,但是把cpu浪费在这种地方有些得不偿失了.
Integer num = 1;
// num先拆箱再比较
while (num < 100000) {
// num先拆箱,然后执行++再装箱
num++;
// do something
}
使用建议
关于使用需要了解两方的优势: 对于基本类型: 优点速度快,内存占用低,缺点无法表示不存在情况 对于包装类型: 优点有null值代表不存在情况,缺点速度慢,内存占用高(相对于基本类型) 那么基本类型与包装类型就是互补的存在了,具体使用哪个根据你是否有值不存在的这一情况表示决定. 日常开发建议遵循阿里Java开发手册:
- (强制)所有POJO类属性必须使用包装类型
- (强制)RPC方法返回值和参数必须包装类型
- (推荐)所有局部变量使用基本类型
其他
最后推荐下一款反编译插件,可以直接看到去糖后的代码 https://github.com/mrdear/asm-bytecode-intellij
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 视频高速上云网关/网络穿透EasyNTS智能组网服务平台ini配置文件丢失如何处理?
- 结构与算法(05):二叉树与多叉树
- 树莓派综合项目2:智能小车(二)tkinter图形界面控制
- 虚拟机系列 | JVM运行时数据区
- 虚拟机系列 | 执行引擎和垃圾回收
- 在Linux系统中编译ARM版EasyNTS上云网关服务报undefined错误的解决方案
- 从全备中恢复单库或单表,小心有坑!
- Zookeeper安装以及常用操作
- Codeforces Round 671 (Div. 2) A-D
- 程序中并没有走缓存,为什么执行时间短了
- ES 常用Linux查询命令汇总
- PostgreSql 怎么获取数据库中关键系统信息(一)
- 树莓派基础实验36:通用串口通信实验
- PIMPL:休想窥探我的隐私!
- 树莓派基础实验37:pyserial模块通信实验