往往我们在编程时会思考传进方法体内的对象是引用传递还是值传递
我们先看看java是怎么玩的
public class Class1 {
public int i = 0;
public void pr()
{
System.out.println(i);
}
}
public class Main {
public static void main(String[] args) {
Class1 c1 = new Class1();
c1.i = 9;
System.out.println(c1.i);
test(c1);
System.out.println(c1.i);
Class1 c2 = c1;
c1 = null;
c2.pr();
c1.pr();
}
public static void test(Class1 cc)
{
//cc = new Class1();
cc.i = 10;
}
}
输出结果
9
10
10
异常
去掉
//cc = new Class1();
注释
输出
9,
9
9
异常
对比下c#的代码:
public class Class1
{
public int i = 0;
public void pr()
{
Console.WriteLine(i);
}
}
private void button1_Click(object sender, EventArgs e)
{
Class1 c1 = new Class1();
c1.i = 9;
Console.WriteLine(c1.i);
test(c1);
Console.WriteLine(c1.i);
Class1 c2 = c1;
c1 = null;
c2.pr();
c1.pr();
}
public void test(Class1 cc)
{
//cc = new Class1();
cc.i = 10;
}
点击button后输出内容为以下:
9
10
10
异常
去掉
//cc = new Class1();
这段代码的注释我们再看看结果
9
9
9
异常
综上不难看出一个问题,两者在处理对象实际上都是值传递,但是在内存使用时你感觉是传的引用,因为地址值没有变化,只是在指向的内存的内容上产生了变化
关键的步骤如下图所示:
在test不new如下
第一步:
c1出现并将信息传给cc,此时cc也指向9
第二步:
cc将指向的内容改为10,执行完成cc销毁,c2和c1指向同一内容
第三步:
此时c1和cc均已无效
test里new对象流程如下:
第一步:
此时cc和c1指向内容相同
第二步
cc指向新对象c1还是老的
第三步:
由于c1内容没有发生修改c2和c1都是9
第四步:
c1置null后销毁c2为有效信息
但是我们看下c#加了ref后的效果
private void button1_Click(object sender, EventArgs e)
{
Class1 c1 = new Class1();
c1.i = 9;
Console.WriteLine(c1.i);
test(ref c1);
Console.WriteLine(c1.i);
Class1 c2 = c1;
c1 = null;
c2.pr();
c1.pr();
}
public void test(ref Class1 cc)
{
cc = new Class1();
cc.i = 10;
}
输出结果:
9
10
10
异常
分析图如下:
第一步:
第二步:
第三步:
第四步:
以上内容仅供参考,是我自己的理解。不对请大神们指点,非常感谢!!!!!