“合抱之木,生于毫末;九层之台,起于累土。” 很多人对基础知识的巩固不够重视。Java 基础就如同大厦的基石,没有稳固的基石,再宏伟的架构也只是空中楼阁。
检验知识是否学得牢固,有一个比较好的办法,假设现在有个面试官问你这个问题,你是否脑瓜子嗡嗡的呢?
往期我们讨论过的主题有:
1.Java 基本数据类型有哪几种?它们各自所占的字节数是多少?
这里补充一下默认值
byte、short、int的默认值为0
long的默认值为0L
float的默认值为0.0f
double的默认值为0.0d
char的默认值为'\u0000'
boolean的默认值为false
为了全面掌握基础知识,我们计划形成基础知识100问,破解大多数的JAVA面试涉及到的基础问题,不用去背八股文,掌握好基础就能灵活应对面试官的提问。
今天是第二问,咱们探讨的内容是:"自动装箱和拆箱是如何实现的?在什么场景下会自动发生?"
试想一下,如果不往下看,你是否能够完整地回答出这个问题呢? 如果答案是肯定的,那恭喜你,你可以节约些时间去学习别的知识了! 当然,“温故而知新”,如果您不忙的话,接着往下看也无妨。
自动装箱和拆箱的概念
在 Java 中,基本数据类型(如 int、double 等)和对应的包装类(如 Integer、Double 等)之间可以进行自动转换,这个过程分别被称为自动装箱(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("条件为真");
}
需要注意的是,虽然自动装箱和拆箱带来了代码编写的便利,但在性能敏感的场景下,频繁的装箱和拆箱操作可能会影响性能,因为涉及到对象的创建和销毁。
本文暂时没有评论,来添加一个吧(●'◡'●)