当前位置:  开发笔记 > 编程语言 > 正文

什么是拳击和拆箱以及有什么权衡取舍?

如何解决《什么是拳击和拆箱以及有什么权衡取舍?》经验,为你挑选了4个好方法。

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

理想情况下,作为实际答案,虽然欢迎链接到良好的解释.



1> Peter Burns..:

盒装值是围绕基本类型*的最小包装器的数据结构.盒装值通常存储为堆上对象的指针.

因此,盒装值使用更多内存并至少需要两次内存查找才能访问:一次获取指针,另一次跟随指向该基元的指针.显然,这不是你想要在内循环中的那种东西.另一方面,盒装值通常与系统中的其他类型相比更好.由于它们是该语言中的一流数据结构,因此它们具有其他数据结构所具有的预期元数据和结构.

在Java和Haskell中,泛型集合不能包含未装箱的值..NET中的通用集合可以保留未装箱的值而不会受到惩罚.在Java的泛型仅用于编译时类型检查的情况下,.NET将为在运行时实例化的每个泛型类型生成特定的类.

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

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

**我也在这个答案中专注于Java,Haskell和C#,因为这就是我所知道的.对于它的价值,Python,Ruby和Javascript都只有盒装价值.这也被称为"一切都是对象"的方法***.

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


Javascript有所谓的类型化数组(新的UInt32Array等),它是未装箱的int和浮点数组.

2> Christian Ha..:

来自C#3.0的坚果壳:

Boxing是将值类型转换为引用类型的行为:

int x = 9; 
object o = x; // boxing the int

拆箱是......相反的:

// unboxing o
object o = 9; 
int x = (int)o; 



3> Justin Stand..:

装箱和拆箱是将原始值转换为面向对象的包装类(装箱),或将值从面向对象的包装类转换回原始值(拆箱)的过程.

例如,在java中,如果要将int值存储为a ,则可能需要将值转换为Integer(装箱),Collection因为基元不能存储在Collection仅对象中.但是当你想要把它取回时Collection你可能希望得到的价值int而不是Integer那样你就可以取消它.

拳击和拆箱本身并不,但这是一个权衡.根据语言实现,它可能比仅使用基元更慢且占用更多内存.但是,它还可以允许您使用更高级别的数据结构,并在代码中实现更大的灵活性.

目前,它最常见于Java(和其他语言)"autoboxing/autounboxing"功能的上下文中.这是一个以java为中心的autoboxing解释.



4> Keith..:

在.Net:

通常,您不能依赖函数将使用的变量类型,因此您需要使用从最小公分母延伸的对象变量 - 在.Net中object.

但是object是一个类并将其内容存储为引用.

List notBoxed = new List { 1, 2, 3 };
int i = notBoxed[1]; // this is the actual value

List boxed = new List { 1, 2, 3 };
int j = (int) boxed[1]; // this is an object that can be 'unboxed' to an int


虽然这两个信息保持相同的信息,但第二个列表更大更慢.第二个列表中的每个值实际上是对object包含该值的引用int.

这称为盒装,因为它int被包装object.当它被退回时,它int被取消装箱 - 转换回它的价值.

对于值类型(即所有structs),这很慢,并且可能使用更多空间.

对于参考类型(即所有classes),这远不是一个问题,因为它们无论如何都被存储为参考.

盒装值类型的另一个问题是,您处理盒子而不是值时并不明显.当你比较两个structs然后你比较值时,但当你比较两个classes然后(默认情况下)你比较参考 - 即这些是同一个实例?

处理盒装值类型时,这可能会造成混淆:

int a = 7;
int b = 7;

if(a == b) // Evaluates to true, because a and b have the same value

object c = (object) 7;
object d = (object) 7;

if(c == d) // Evaluates to false, because c and d are different instances

解决方法很容易:

if(c.Equals(d)) // Evaluates to true because it calls the underlying int's equals

if(((int) c) == ((int) d)) // Evaluates to true once the values are cast

但是在处理盒装值时要小心另一件事.

推荐阅读
臭小子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有