您的位置:首页 > 其它

引用类型和值类型在方法调用中的异同?

2005-09-26 13:25 190 查看
刚才在CSDN上有一篇很hot的帖子,地址: http://community.csdn.net/Expert/topic/4292/4292562.xml?temp=.4954492 搞得我也甚是头晕

,因为对JIT编译器的内部运作情况还真是不了解,这里先简单说下我的想法.
先简单说下值类型和引用类型的区别:
1.值类型在栈上分配,定义了一个貌似Int32 i=123 这样的值变量之后,i 变量包含的是123这个实体,不包含地址值,但是刚才也有人说i其实也是在栈上有地址的---栈地址,这点我也认同.

2.引用类型: 引用类型是在托管堆上分配的,貌似这样的 Object o=new Object(); 编译器看到这一句以后,先在托管堆上分配给一块连续的内存用于包含“值”实体内容,至于还分配了方法表的指针和一个SyncBlockIndex,那是后话.然后就是把这块内存地址返回给o保存.

下面来说说方法调用的情况:

1.没有ref或out限制,参数为值类型,这没什么好说的,也就是把栈上的实体内容深拷贝到虚参里去,从而不对原来的实参构成影响.

2.有ref或out限制,虚参为引用类型,也没什么好说的,传递的是引用参数保存的内存地址。
------------------------------------------
3.像这样的调用
public static void change(ref Int32 newi)//实参为Int32 oldi
很明显,实参oldi是一个值类型,不能储存地址,储存的是实体本身。
在change方法中,参数ref Int32 newi实际上也是申明了一个新的变量,因为前面有ref限制了,我的看法是:编辑器看到这个ref关键词以后,可以看到il代码中,这里的写法实际上是Int32 & ,按照C++的观点,是用newi这个地址(因为有&修饰)去指向oldi包含的实体内容。
所以,我的假想认为编译器在这里的做法就是:告诉newi这个地址去指向oldi的实体,在方法调用完毕之后,因为change方法已经把内存中oldi包含的实体改变了,所以再WriteLine的时候,就得到了新值!

4.像这样的调用
public static void change(Object newo)//实参为Object oldo
这里用的是传值调用,参数是引用类型。
newo是一个地址值,保存的new obj后返回的内存地址。
我在这里的假想是:编译器的做法是把oldo的地址拷贝过来以后,因为newo是一个新定义的引用变量,编译器就告诉newo,只是取出oldo指向内存的实体,并且返回一个新的地址给newo,而不要又指向原来oldo保存的原始内存地址。
当调用完毕之后,因为是新的内存地址,所以对原来的没有影响。
------------------------------
这些是我的假设,各位不知道有没有看法?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐