98. Java 数字和字符串 - 自动装箱和取消装箱

22 阅读3分钟

98. Java 数字和字符串 - 自动装箱和取消装箱

什么是自动装箱和取消装箱?

自动装箱Autoboxing)是 Java 编译器在基元类型(Primitive Type)与其对应的**包装类(Wrapper Class)**之间进行的自动转换。例如,将 int 转换为 Integer,将 double 转换为 Double,等等。**取消装箱(Unboxing)**是相反的操作,即将包装类的对象转换回其对应的基元类型。

自动装箱示例

Character ch = 'a'; // char 自动装箱为 Character

在泛型集合中,自动装箱尤为常见。例如:

List<Integer> ints = new ArrayList<>();
for (int i = 1; i < 50; i += 2) {
    ints.add(i); // int 自动装箱为 Integer
}

尽管 intsInteger 类型的 List,但 int 类型的 i 仍然可以直接添加进去。Java 编译器在编译时会自动转换为:

ints.add(Integer.valueOf(i));

什么时候会发生自动装箱?

Java 编译器会在以下两种情况自动装箱:

  1. 当基元类型的值赋给对应包装类的变量时:

    Integer num = 10; // int 自动装箱为 Integer
    
  2. 当基元类型作为参数传递给需要包装类的对象方法时:

    List<Double> doubleList = new ArrayList<>();
    doubleList.add(3.14); // double 自动装箱为 Double
    

取消装箱(Unboxing

取消装箱是指 Java 编译器将包装类对象转换回其对应的基元类型。例如:

Integer num = Integer.valueOf(42);
int value = num; // Integer 取消装箱为 int

Java 编译器会在以下情况自动执行取消装箱:

  1. 当包装类对象赋值给基元类型变量时:

    Integer obj = Integer.valueOf(100);
    int num = obj; // 取消装箱
    
  2. 当包装类对象作为参数传递给需要基元类型的方法时:

    public static int square(int x) {
        return x * x;
    }
    Integer obj = 5;
    int result = square(obj); // Integer 取消装箱为 int
    

取消装箱示例

import java.util.ArrayList;
import java.util.List;

public class UnboxingDemo {
    public static void main(String[] args) {
        Integer i = Integer.valueOf(-8);

        // 1. 通过方法调用进行取消装箱
        int absVal = absoluteValue(i);
        System.out.println("绝对值: " + absVal);

        List<Double> doubleList = new ArrayList<>();
        doubleList.add(3.1416); // double 自动装箱为 Double

        // 2. 通过赋值进行取消装箱
        double pi = doubleList.get(0); // Double 取消装箱为 double
        System.out.println("pi = " + pi);
    }

    public static int absoluteValue(int i) {
        return (i < 0) ? -i : i;
    }
}

运行结果:

绝对值: 8
pi = 3.1416

自动装箱和取消装箱的好处

代码更简洁:无需手动调用 valueOf()intValue()。 ✅ 更易读:避免显式转换,使代码逻辑更直观。 ✅ 泛型集合兼容性:允许使用基元类型,但底层仍然存储对象。

Java 8 及以上版本的注意事项

虽然自动装箱和取消装箱非常方便,但过度使用可能会导致性能下降,尤其是在大规模循环或高频率操作中。建议

  • 优先使用基元类型:在可能的情况下,避免包装类的额外开销。
  • 注意 null 处理:包装类可以为 null,而基元类型不允许 null,需小心 NullPointerException

Java 包装类对应表

基元类型(Primitive Type)包装类(Wrapper Class)
booleanBoolean
byteByte
charCharacter
floatFloat
intInteger
longLong
shortShort
doubleDouble

自动装箱和取消装箱是 Java 语法糖的一部分,使得代码更加优雅,但需要注意避免不必要的性能损耗。🚀