专业的JAVA编程教程与资源

网站首页 > java教程 正文

JAVA自动装箱和拆箱是如何实现的?在什么场景下会自动发生?

temp10 2025-02-28 17:27:55 java教程 10 ℃ 0 评论

“合抱之木,生于毫末;九层之台,起于累土。” 很多人对基础知识的巩固不够重视。Java 基础就如同大厦的基石,没有稳固的基石,再宏伟的架构也只是空中楼阁。


JAVA自动装箱和拆箱是如何实现的?在什么场景下会自动发生?

检验知识是否学得牢固,有一个比较好的办法,假设现在有个面试官问你这个问题,你是否脑瓜子嗡嗡的呢?



往期我们讨论过的主题有:


1.Java 基本数据类型有哪几种?它们各自所占的字节数是多少?


这里补充一下默认值


byte、short、int的默认值为0

long的默认值为0L

float的默认值为0.0f

double的默认值为0.0d

char的默认值为'\u0000'

boolean的默认值为false


为了全面掌握基础知识,我们计划形成基础知识100问,破解大多数的JAVA面试涉及到的基础问题,不用去背八股文,掌握好基础就能灵活应对面试官的提问。


今天是第二问,咱们探讨的内容是:"自动装箱和拆箱是如何实现的?在什么场景下会自动发生?"


试想一下,如果不往下看,你是否能够完整地回答出这个问题呢? 如果答案是肯定的,那恭喜你,你可以节约些时间去学习别的知识了! 当然,“温故而知新”,如果您不忙的话,接着往下看也无妨。



自动装箱和拆箱的概念

在 Java 中,基本数据类型(如 intdouble 等)和对应的包装类(如 IntegerDouble 等)之间可以进行自动转换,这个过程分别被称为自动装箱(Autoboxing)和自动拆箱(Unboxing)。自动装箱是指将基本数据类型自动转换为对应的包装类对象;自动拆箱则是将包装类对象自动转换为对应的基本数据类型。

实现原理

自动装箱

自动装箱是通过调用包装类的 valueOf() 方法实现的。以下是一个示例代码及对应的字节码分析:

public class AutoboxingExample {
    public static void main(String[] args) {
        int num = 10;
        Integer integerObj = num; // 自动装箱
    }
}

使用 javap -c 命令查看字节码,会发现自动装箱实际上调用了 Integer.valueOf() 方法:

Compiled from "AutoboxingExample.java"
public class AutoboxingExample {
  public AutoboxingExample();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."":()V
       4: return
  public static void main(java.lang.String[]);
    Code:
       0: bipush        10
       2: istore_1
       3: iload_1
       4: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       7: astore_2
       8: return
}

自动拆箱

自动拆箱是通过调用包装类的 xxxValue() 方法实现的,其中 xxx 表示对应的基本数据类型。示例代码及字节码分析如下:

public class UnboxingExample {
    public static void main(String[] args) {
        Integer integerObj = 10;
        int num = integerObj; // 自动拆箱
    }
}

字节码显示自动拆箱调用了 Integer.intValue() 方法:

Compiled from "UnboxingExample.java"
public class UnboxingExample {
  public UnboxingExample();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."":()V
       4: return
  public static void main(java.lang.String[]);
    Code:
       0: bipush        10
       2: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       5: astore_1
       6: aload_1
       7: invokevirtual #3                  // Method java/lang/Integer.intValue:()I
      10: istore_2
      11: return
}


自动发生的场景

自动装箱发生的场景

赋值操作

将基本数据类型赋值给对应的包装类对象时会自动装箱。

int a = 20;
Integer b = a; // 自动装箱

方法调用

当方法参数为包装类对象,而传入的是基本数据类型时会自动装箱。

public static void printInteger(Integer num) {
    System.out.println(num);
}
public static void main(String[] args) {
    int num = 30;
    printInteger(num); // 自动装箱
}

自动拆箱发生的场景

赋值操作

将包装类对象赋值给对应的基本数据类型时会自动拆箱。

Integer c = 40;
int d = c; // 自动拆箱

算术运算

在进行算术运算时,如果操作数中有基本数据类型和包装类对象,包装类对象会自动拆箱。

Integer e = 50;
int f = e + 10; // 自动拆箱

条件判断

在条件判断语句中,如果需要基本数据类型的布尔值,包装类对象会自动拆箱。

Boolean boolObj = true;
if (boolObj) { // 自动拆箱
  System.out.println("条件为真");
}

需要注意的是,虽然自动装箱和拆箱带来了代码编写的便利,但在性能敏感的场景下,频繁的装箱和拆箱操作可能会影响性能,因为涉及到对象的创建和销毁。



本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表