简单一点,引用传递和值传递的区别:值传递是传递了原有对象的一个副本,所以调用函数可以改变副本的值,但是对原有对象没有任何影响 引用传递是传递了对象的引用,对引用的操作会改变源对象本身
测试类:
public class A { public String name; public String sex; }
public class B { public String name; public String sex; }
public class C { public String name; public String sex; public B b; }
测试:
(1)
代码:
public static void main(String[] args) { A a = new A(); a.name = "刘备"; System.out.println(a.name); test1(a); System.out.println(a.name); } public static void test1(A a){ a.name = "关羽"; System.out.println(a.name); }
输出:
刘备
关羽
关羽
(2)
代码:
public static void main(String[] args) { A a = new A(); System.out.println(a); test1(a); System.out.println(a); } public static void test1(A a){ a = new A(); System.out.println(a); }
输出:
test.A@179d3b25
test.A@254989ff
test.A@179d3b25
(3)
代码:
public static void main(String[] args) { A a = new A(); a.name = "刘备"; System.out.println(a.name); test1(a.name); System.out.println(a.name); } public static void test1(String name){ name = "关羽"; System.out.println(name); }
输出:
刘备
关羽
刘备
(4)
代码:
public static void main(String[] args) { A a = new A(); a.name = "刘备"; System.out.println(a.name); test1(a); System.out.println(a.name); } public static void test1(A a){ a = new A(); a.name = "关羽"; System.out.println(a.name); }
输出:
刘备
关羽
刘备
(5)
代码:
public static void main(String[] args) { C c = new C(); c.b = new B(); System.out.println(c.b); test1(c); System.out.println(c.b); } public static void test1(C c){ c.b = new B(); System.out.println(c.b); }输出:
test.B@179d3b25
test.B@254989ff
test.B@254989ff
以上就是我想到的各种情况了,针对点说吧
(1)一开始main函数中新增了一个对象A,也就是开辟了一块内存1,内存1中有个name的值为刘备。然后将内存1的地址传给test1方法,也就是说test1拿到的地址是指向内存1的,然后将内存1的name的值修改为关羽。因此内存1中储存的name最终为关羽
(2)一开始main函数中新增了一个对象A,也就是开辟了一块内存1,内存1的地址为test.A@179d3b25。然后将内存1的地址传给test1方法,然后test1方法中又新增了一个对象A,也就是test1中的a的地址从此为test.A@254989ff,因此最终会有两块内存test.A@179d3b25、test.A@254989ff,毫不相干
(3)典型的值传递,就不废话了
(4)跟例2有点像,当进入test1方法时,test1方法自己开辟了一块内存2,其后的修改都是基于内存2中的内容进行修改,与main函数中的内存1没啥关系
(5)针对例1的补充吧
C#的设计就相对合理,函数声明里,有ref/out,就是引用传递,没有ref/out,就是值传递,与参数类型无关。