自动装箱与自动拆箱

    技术2026-03-15  9

    文章目录

    一、前言对象包装器 二、自动装箱与自动拆箱自动装箱与自动装箱何时发生 三、对象包装器对象之间的比较四、Integer 类常用 API

    一、前言

    提到自动装箱与自动拆箱就要先说对象包装器。

    指路个人博客

    对象包装器

    Java 有八种基本类型,可以简单地进行数据处理。但是由于 Java 是面向对象语言,而八种基本数据类型不支持面向对象编程,比如使用集合时,是无法将 int 这种基本类型放进去的,为了方便开发,Java 针对每个基本类型设计了对应的对象包装器(wrapper)。

    基本数据类型对象包装器byteByteshortShortintIntegerlongLongfloatFloatdoubleDoublecharCharacterbooleanBoolean

    我们要注意:

    一旦构造了包装器,不允许更改包装器中的值。对象包装器类不能定义子类。

    可以简单看一下 Integer 源码找一下原因:

    public final class Integer extends Number implements Comparable<Integer> {

    可以看到 Integer 类使用 final 修饰,所以不能被继承,也就不能有子类。

    我们继续看 Integer 的构造器:

    public Integer(int value) { this.value = value; }

    看到包装器中的值使用 value 存储的,我们再看一下 value 的定义:

    private final int value;

    可以看到 value 是使用 final 修饰的,所以包装器类一旦创建对象,里面的值不能改变。

    二、自动装箱与自动拆箱

    基本类型比如 int 自动的转化为包装器类型比如 Integer 称为自动装箱(autoboxing)。

    相反的,将包装器类型比如 Integer 自动转化为 int 类型,称为自动拆箱(autounboxing)。

    那么什么时候会发生自动拆箱与自动装箱呢?

    自动装箱与自动装箱何时发生

    将一个基本类型赋值给对象包装器对象,就会发生自动装箱。比如:

    List<Integer> list = new ArrayList<>(); // 此处发生自动装箱:相当于 list.add(Integer.valueOf(3)) list.add(3);

    将一个包装器对象赋值给基本类型,就会发生自动拆箱。比如:

    List<Integer> list = new ArrayList<>(); // 此处发生自动装箱:相当于 list.add(Integer.valueOf(3)) list.add(3); // 此处发生自动拆箱:相当于 list.get(0).intValue(); list.get(0);

    算术表达式也可以发生自动装箱与自动拆箱操作,比如自增与自减操作:

    Integer n = 3; // n 先自动拆箱,做完减法后,自动装箱 n--;

    如果在一个条件表达式中混合使用 Integer 和 Double 类型,Integer 值就会自动拆箱,转化为 double,再自动装箱提升为 Double 值。

    Integer a = 1; Double b = 2.0; // 1.0 System.out.println(true? a : b);

    三、对象包装器对象之间的比较

    由于自动装箱和自动拆箱,使我们觉得对象包装器对象之间的比较,好像使用 == 运算符也可以,== 运算符运用在对象之间,实际是比较对象是否指向同一个内存区域。那么我们猜测一下,下面代码运行的结果是多少:

    Integer i1 = 100; Integer i2 = 100; System.out.println(i1 == i2); Integer i3 = 300; Integer i4 = 300; System.out.println(i3 == i4); Integer i5 = new Integer(100); Integer i6 = new Integer(100); System.out.println(i6 == i5);

    程序的运行结果为:

    true false false

    那么为什么是这样的结果呢?

    自动装箱规范要求 boolean、byte、char <= 127,介于 -128 ~ 127 之间的 short 和 int 被包装到固定的对象中。(此句话出自 Java 核心技术卷 1 的 185 页)

    所以 i1 和 i2 其实指向的是一个对象,所以为 true。i3 与 i4 指向的是两个对象,所以为 false。而 i5 和 i6 不是自动装箱,属于手动装箱,所以不遵守自动装箱规范,也是两个对象,所以为 false。

    所以还是推荐使用 equals() 来对对象包装器对象进行比较,equals() 在 Integer 中被重写,作用是比较包装器对象中的值,我们可以看一下源码:

    public boolean equals(Object obj) { // 当前对象与 obj 是否为同一类型,不是同一类型无法比较,返回 false if (obj instanceof Integer) { // obj 强转为 Integer 后进行手动拆箱转化为 int 值,与 value(前面分析过了,value 是包装器对象实际存储值的地方)进行比较 return value == ((Integer)obj).intValue(); } return false; }

    所以只要对象包装器对象中的值相同,则 equals()

    四、Integer 类常用 API

    方法作用int intValue()以 int 的形式返回 integer 对象的值static String toString(int i, int radix)以一个新的 String 对象形式返回给定数值 i 的十进制表示static int parseInt(String s)返回字符串表示的整型数值,十进制数static int parseInt(String s, int radix)返回字符串表示整型数值,radix 参数类型的数static Integer valueOf(String s)返回用 s 表是的整型数值进行初始化的一个新 Integer 对象,十进制数static Integer valueOf(String s, int radix)返回用 s 表是的整型数值进行初始化的一个新 Integer 对象,radix 参数进制数
    Processed: 0.008, SQL: 9