深入解析装箱和拆箱

深入解析装箱和拆箱,第1张

深入解析装箱和拆箱

文章目录

目录

文章目录

前言

一、什么是堆栈?

二、值类型和引用类型

1.细节

2.在堆栈上分布

三、字符串

四、装箱和拆箱

总结



前言

装箱和拆箱其实是对内存的 *** 作,确切的说是堆栈的数据切换,在深入的说是值类型和引用类型的切换;

一、什么是堆栈?
  • 堆栈都是在内存上开辟一块空间,供程序调用;
  • 栈是为线程提供资源,每个线程有单独的线程栈,线程结束对应的线程栈资源释放.线程栈的资源分配是链表式的,内存地址不连续(速度快,但是容易产生内存碎片,浪费资源);
  • 堆是为进程提供资源,一个程序只有一个进程,一个进程只有一个进程堆.进程堆的资源分配是数字式的,地址连续(为了节省资源);

二、值类型和引用类型 1.细节

值类型:包括数值、枚举、结构体,通常情况下值是存放在栈上,可以直接调用

引用类型:包括字符串、类、泛型、委托,资源值是存放在堆上,指向堆的地址存放在栈上

2.在堆栈上分布

 引用类型:无论如何都会在堆上分配资源;

值类型:如果在应用类型下的属性字段,是分配在堆上的,其它是分配在栈上

方法的值类型:分配在栈上

三、字符串

字符串比较特殊,单独说一下;

字符串有个池的概念,即设计模式的享元模式;字符串的值会单独存放在一个字符串池里,我们只能改变指向字符串的地址,不能改变字符串的值,如下图

为什么字符串要这么麻烦?因为堆的资源是连续分配的,如果字符串发生改动,那么字符串之后的所有地址都要改动,代价太大.所以用字符串池,字符串发生改动,只改动地址引用,这字符串后面的资源没有影响;

四、装箱和拆箱

堆栈如果搞清楚了,装箱和拆箱就很简单了,无非就是堆栈地址的来回复制罢了;

值类型:int i=>object obj ,装箱从栈放到堆上,可以跨栈使用,object obj=>int i 拆箱,从堆到栈

字符串类型:string str=>object obj,装箱从字符串池到堆,object obj=>string str,拆箱从堆到字符串

class类型:class cls=>object obj,装箱从堆到堆,object obj=>class cls,拆箱从堆到堆

net的装箱和拆箱,一般专职oject类型和其他类型的转换;随着语言的进步,装箱和拆箱的使用场景越来越少了,下面讲一下装箱和拆箱的应用场景及替代语言

1.object作为参数,可以将任何类型封箱成object传入,再拆箱使用;被泛型替代;

2.object作为接收类型,很多情况下不知道会传入什么类型的值,只好用object接收,winform还有很多这种做法,例如datagridview的每个单元格的值内容就是object的,使用时要拆箱;大多数情况可以用dynamic类型替代

装箱和拆箱很多时候是为了应对不确定性而使用,例如参数的不确定性和返回值的不确定性,随着技术的发展,有更多的技术替代,像泛型/反射/dynamic等等,装箱和拆箱的使用场景越来越小,但是有特殊的场景用装箱和拆箱反而更好,想逆变和协变的接收转换;


总结

封箱和拆箱,随着语言的变迁,使用场景越来越少了,但是他的核心思想却从未褪色,尤其是关于内存 *** 作的部分更要细细琢磨,因为内存 *** 作是很多技术的核心思想,而且都是通用的

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5686574.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存