探寻Java装箱和拆箱的奥妙!

简介: Java中的装箱和拆箱技术经历了从手动到自动、从普通到紧凑型的演进,这使得我们能够更方便地操作基本数据类型和封装类型之间的转换。

前言

  今天在逛某知名论坛的时候,看到一篇"请不要使用包装类型,避免造成性能损失"的文章。一下子就吸引了我的注意。大意就是,能用基本数据类型就尽量用基本数据类型,因为包装类型自动拆箱、装箱会带来性能损失尤其是循环使用时会大量创建对象。所以今天聊一下,Java的装箱和拆箱。

什么是装箱和拆箱?

  Java中的装箱(boxing)和拆箱(unboxing)是指将基本数据类型与其对应的包装类之间进行转换的过程。

装箱

  装箱是将基本数据类型转换为其对应的包装类,例如将int类型转换为Integer类型。这个过程是通过自动装箱(autoboxing)或手动装箱(manual boxing)完成的。自动装箱是指Java编译器自动将基本类型转换为包装类型,而手动装箱则是通过调用包装类的构造函数来完成。

拆箱

  拆箱是将包装类转换为其对应的基本数据类型,例如将Integer类型转换为int类型。这个过程也是通过自动拆箱(autounboxing)或手动拆箱(manual unboxing)完成的。自动拆箱是指Java编译器自动将包装类型转换为基本类型,而手动拆箱则是通过调用包装类的xxxValue()方法来完成。

为啥要包装类型?

  在日常使用的时候,感觉用基本类型还是包装类型貌似没啥区别。如果去掉包装类型,那就不需要装箱和拆箱了。也就避免了性能损失。貌似很完美呀。

  如果你是这样想就,大错特错了。java中有基本数据类型和包装类型,这是为了满足不同需求的设计。java大佬们肯定不会做这样的无用功的,使用包装类型的主要原因包括:

  • 对象引用:基本类型不是对象,无法使用对象引用,而包装类型是对象,可以通过引用来操作。

  • 泛型:泛型不能使用基本数据类型,必须使用包装类型。如,使用List<Integer>来存储一组整数,而不是使用List<int>

  • null值:基本类型不能为null,而包装类型可以为null。

  • 类型转换:包装类型提供了许多类型转换方法,例如将字符串转换为整数或浮点数等,这些方法非常方便。

  • 方法重载:方法重载可以使用不同的参数类型,但是基本数据类型和其对应的包装类型在方法中被认为是不相同的类型,因此可以在方法中使用它们进行重载。

  尽管基本数据类型在Java中非常有用,但是包装类型提供了更多的功能和灵活性,因此在某些情况下使用包装类型会更为方便和实用。所以就有了装箱和拆箱的过程。

装箱和拆箱的进化过程

  在Java 1.4及之前,装箱和拆箱需要手动进行,即需要使用对应的构造函数或方法来完成。例如,要将int类型的变量x装箱成Integer类型,可以使用以下代码:

int x = 10;
Integer y = new Integer(x);  // 手动装箱

要将Integer类型的变量y拆箱成int类型,可以使用以下代码:

Integer y = new Integer(10);
int x = y.intValue();  // 手动拆箱

  这种方式比较繁琐,也容易出错。因此,从Java 5开始,引入了自动装箱和拆箱机制。这意味着我们可以直接将基本数据类型赋值给对应的封装类型变量,或将封装类型变量赋值给对应的基本数据类型变量,编译器会自动完成转换。例如:

int x = 10;
Integer y = x;  // 自动装箱
int z = y;  // 自动拆箱

  从Java 9开始,引入了一种新的装箱方式,称为“紧凑型装箱”(Compact Number Box),它能够更高效地存储小范围内的数值。紧凑型装箱只适用于byte、short和int类型的封装类型,这些类型的取值范围都比较小(如byte的取值范围为-128到127),因此可以使用一个byte或short类型的变量来存储它们的值,而无需使用一个整型变量。

到底该如何选择呢?

  基本类型是Java语言的基础,可以直接存储在栈中,具有较高的执行效率和较小的内存占用。包装类型是把基本类型封装起来的对象,可以在堆中存储,可以进行各种面向对象的操作。所以在选择使用基本类型还是包装类型时,可以考虑以下几个因素:

  1. 执行效率:基本类型具有较高的执行效率,尤其是在大量计算的情况下,使用基本类型可以明显提高程序的执行速度。

  2. 内存占用:基本类型在栈中存储,占用的内存较小,而包装类型在堆中存储,占用的内存较大。

  3. 对象操作:如果需要进行面向对象的操作,例如通过equals()方法比较两个变量的值,或者将基本类型转换为字符串,就需要使用包装类型。

  4. 空值处理:基本类型不能表示空值,而包装类型可以用null表示空值,因此在需要处理空值的情况下,需要使用包装类型。

总结

  Java中的装箱和拆箱技术经历了从手动到自动、从普通到紧凑型的演进,这使得我们能够更方便地操作基本数据类型和封装类型之间的转换。虽然更加方便, 但是在实际开发中,还是需要根据具体的使用场景进行选择。

结尾

  如果觉得对你有帮助,可以多多评论,多多点赞哦,也可以到我的主页看看,说不定有你喜欢的文章,也可以随手点个关注哦,谢谢。

  我是不一样的科技宅,每天进步一点点,体验不一样的生活。我们下期见!

相关文章
|
4月前
|
存储 Java 编译器
Java零基础(12) - 自动装箱
【8月更文挑战第12天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
35 2
|
4月前
|
Java
【Java基础面试九】、说一说自动装箱、自动拆箱的应用场景
这篇文章介绍了Java中的自动装箱和自动拆箱概念:自动装箱允许将基本类型赋值给对应的包装类对象,而自动拆箱允许将包装类对象赋值给基本类型,从而简化了两者之间的转换过程。
【Java基础面试九】、说一说自动装箱、自动拆箱的应用场景
|
4月前
|
存储 缓存 Java
Java零基础教学(13):自动拆箱与自动装箱详解
【8月更文挑战第13天】Java零基础教学篇,手把手实践教学!
47 1
Java零基础教学(13):自动拆箱与自动装箱详解
|
4月前
|
存储 Java 编译器
Java零基础(17) - 自动拆箱与自动装箱
【8月更文挑战第17天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
47 3
|
4月前
|
存储 Java 测试技术
Java零基础教学(11):自动装箱
【8月更文挑战第11天】Java零基础教学篇,手把手实践教学!
59 5
|
4月前
|
Java 编译器 测试技术
Java零基础(13) - 自动拆箱
【8月更文挑战第13天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
34 2
|
4月前
|
Java 编译器 测试技术
Java零基础教学(12):自动拆箱
【8月更文挑战第12天】Java零基础教学篇,手把手实践教学!
38 2
|
5月前
|
监控 Oracle Java
(一)JVM成神路之初识虚拟机 - 探寻Java虚拟机的前世今生之秘
JVM(Java Virtual Machine)Java虚拟机的概念大家都不陌生,Java之所以可以做到“一次编译,到处运行”的跨平台性,其根本原因就在于JVM。JVM是建立在操作系统(OS)之上的,Java虚拟机屏蔽了开发人员与操作系统的直接接触,我们在通过Java编写程序时,只需要负责编写Java代码即可,关于具体的执行则会由JVM加载字节码后翻译成机械指令交给OS执行。
|
5月前
|
Java 编译器 测试技术
day19:Java零基础 - 自动装箱
【7月更文挑战第19天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
59 4
|
5月前
|
存储 Java 测试技术
day20:Java零基础 - 自动拆箱
【7月更文挑战第20天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
43 2