password
last_edited_time
Jul 21, 2023 02:27 PM
type
status
date
slug
summary
tags
category
icon
什么是自动装箱和拆箱
自动装箱和拆箱(Autoboxing and Unboxing):
Java
编译器(编译源码时)在 基本数据类型及其对应的包装类(the primitive types and their corresponding object wrapper classes)之间进行的自动转换。- 自动装箱 (Autoboxing):将一个基本数据类型变量值转换为一个其对应的包装类对象。例如,将一个
int
变量值转换为一个Integer
对象,将一个double
变量值转换为一个Double
对象,依此类推。 - 自动装箱情况1:作为参数传给一个期望得到相应封装类对象的方法。例:集合框架所有集合类的添加元素操作,如 ArrayList#add(E)
- 自动装箱情况2:将一个基本数据类型变量值分配给其相应的包装类。例:Integer number = 1;
- 拆箱 (Unboxing): 将一个基本数据类型包装类对象转换为一个其对应的基本数据类型变量值。也就是将一个
Integer
对象转换为一个int
变量值,将一个Double
对象转换为double
变量值,依此类推。 - 拆箱情况1: 作为参数传给一个期望得到相应基本数据类型值的方法。例:Math.abs(new Integer(-1));
- 拆箱情况2: 将一个基本数据类型包装类对象分配给其相应的基础数据类型变量。例:int number = new Integer(1);
推出自动装箱和拆箱功能,主要还是为了使代码更加简洁。
简单示例
深究原理
从java代码上看不出自动装箱与拆箱是如何实现自动转换的,所以可以从字节码的层面看。
自动装箱原理
从字节码上可以看出
Integer integer = 10;
最终在编译后会变成Integer integer = Integer.valueOf(10);
,这里附上对应的字节码片段:而在看
Integer#valueOf(int)
方法时也可以看出这个方法是JDK 5
时出现的。自动拆箱原理
从字节码上可以看出
int num = integer;
最终在编译后会变成调用Integer
实例的intValue()
方法,也就是会变成(以上面的代码为例)int num = integer.intValue();
,这里附上对应的字节码片段:拓展
知道了自动装箱和拆箱后,就可以加强对部分代码的运用了。
- 可以直接用基本数据类型(the primitive types)值与其对应的对象包装器类的实例对象进行值大小判断
- 拆箱的时候需要注意:NullPointerException
- 自动装箱的时候需要注意,有的基础数据类型包装器类(如Integer)有对象缓存池的概念
- 为啥要有这个玩意?
- 参考已经解答过的文章
- JDK 8 语言规范中对装箱转换的讲解(附录中有链接)中有原文
- 可以修改池的范围(正数方向的)
- 简单介绍下怎么改(基于jdk1.8.191),以Integer为例
java.lang.Integer.IntegerCache
- 获取当前的配置的值:
VM.getSavedProperty("java.lang.Integer.IntegerCache.high")
- 配置该值:设置虚拟机参数即可,比如设置为255,
Djava.lang.Integer.IntegerCache.high=255
附录A 基本数据类型及其对应的包装类
Primitive type | Wrapper class |
boolean | Boolean |
byte | Byte |
char | Character |
float | Float |
int | Integer |
long | Long |
short | Short |
double | Double |
附录B 相关链接
由于 JDK 5 的相关官方文档已经找不到了(包括新特性与文档),这里就只能参考 JDK 8 的相关文档了