java 中的自动装箱和拆箱
2023-6-20
| 2023-7-21
0  |  0 分钟
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)有对象缓存池的概念
    • 为啥要有这个玩意?
    • 可以修改池的范围(正数方向的)
      • 简单介绍下怎么改(基于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 的相关文档了
 
技术分享
  • java
  • 开发
  • 原理
  • java 中的关键字(更新中)用 VeraCrypt 对磁盘或文件进行加密
    目录