我正在寻找一个清晰、简洁和准确的答案。

理想情况下作为实际答案,尽管欢迎提供良好解释的链接。

最佳答案

盒装值为 data structures,它们是 primitive types * 周围的最小包装器。装箱值通常存储为指向 the heap 上的对象的指针。

因此,装箱值使用更多内存并至少进行两次内存查找来访问:一次获取指针,另一次跟随该指针指向原语。显然,这不是您想要的内循环。另一方面,盒装值通常与系统中的其他类型一起玩得更好。由于它们是该语言中的一流数据结构,因此它们具有其他数据结构所具有的预期元数据和结构。

在 Java 和 Haskell 中,泛型集合不能包含未装箱的值。 .NET 中的通用集合可以保存未装箱的值而不会受到惩罚。 Java 的泛型仅用于编译时类型检查,.NET 将 generate specific classes for each generic type instantiated at run time

Java 和 Haskell 有未装箱的数组,但它们明显不如其他集合方便。但是,当需要峰值性能时,避免装箱和拆箱的开销有点不便是值得的。

* 对于本讨论,原始值是可以存储在 the call stack 上的任何值,而不是存储为指向堆上值的指针。通常这只是机器类型(整数、浮点数等)、结构,有时是静态大小的数组。 .NET-land 称它们为值类型(而不是引用类型)。 Java 人们称它们为原始类型。 Haskellions 只是称它们为未装箱的。

** 在这个答案中,我还关注 Java、Haskell 和 C#,因为这就是我所知道的。就其值(value)而言,Python、Ruby 和 Javascript 都有专门的盒装值。这也称为“一切皆对象”方法***。

*** 警告:在某些情况下,足够先进的编译器/JIT 可以实际检测到在查看源时语义装箱的值在运行时可以安全地是未装箱的值。本质上,多亏了出色的语言实现者,您的盒子有时是免费的。

关于language-agnostic - 什么是装箱和拆箱?有什么取舍?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13055/

10-13 04:58