Java:为什么需要包装类?
2022-09-01 10:18:03
在非常高的层次上,我知道我们需要通过使用它们各自的包装器类在Java集合中使用它们来“包装”基元数据类型,例如int和char。我想通过问:“为什么我们需要将基元数据类型包装为对象才能在集合中使用它们?”来了解Java集合如何在低级别工作?我提前感谢您的帮助。
在非常高的层次上,我知道我们需要通过使用它们各自的包装器类在Java集合中使用它们来“包装”基元数据类型,例如int和char。我想通过问:“为什么我们需要将基元数据类型包装为对象才能在集合中使用它们?”来了解Java集合如何在低级别工作?我提前感谢您的帮助。
因为 Java 集合只能存储对象引用(所以您需要将基元框化以将它们存储在集合中)。
阅读这篇有关自动装箱的短文,了解更多信息。
如果你想要细节,它几乎可以归结为以下内容:
本地基元存储在堆栈上。集合通过对堆中对象的内存位置的引用来存储其值。要获取本地基元的引用,您必须将该值装箱(获取堆栈上的值并将其包装在堆上以存储在堆上)。
在虚拟机级别,这是因为与java.lang.Object及其派生类型等引用类型相比,基元类型在内存中的表示方式非常不同。例如,Java中的基元int在内存中只有4个字节,而一个对象本身至少占用8个字节,另外还有4个字节用于引用它。这种设计简单反映了CPU可以更有效地处理基元类型的事实。
因此,对于您的问题“为什么需要包装器类型”,一个答案是因为它实现了性能改进。
但对于程序员来说,这种区别会增加一些不良的认知开销(例如,不能在集合中使用int和float)。事实上,通过隐藏这种区别来做语言设计是很有可能的,---许多脚本语言都这样做,而CLR就是这样做的。从1.5开始,Java也做到了这一点。这是通过让编译器静默地在基元表示和对象表示(通常称为装箱/取消装箱)之间插入必要的转换来实现的。
所以你的问题的另一个答案是,“不,我们不需要它”,因为编译器会自动为你做这件事,在某种程度上,你可以忘记幕后发生的事情。