值传递:
如果参数类型是八种基本类型,那么传过来的就是这个参数的一个副本,也就是这个原始参数的值,这个跟之前所谈的传值是一样的。如果在函数中改变了副本的值不会改变原始的值.
址传递
如果参数类型是引用类型,那么传过来的就是这个引用参数的副本,这个副本存放的是参数的地址。
如果在函数中没有改变这个副本的地址,而是改变了地址中的值,那么在函数内的改变会影响到传入的参数。
如果在函数中改变了副本的地址,如new一个,那么副本就指向了一个新的地址,等函数结束,副本的生命周期也就结束了。而传入的参数还是指向原来的地址,所以不会改变参数的值。
看一段代码:
public class T180806 {
public static void main(String[] args) {
MyNum c1 = new MyNum(2);
MyNum c = new MyNum(1);
Test(c,c1);
System.out.println("c = "+c);
System.out.println("c1 = "+c1);
}
static void Test(MyNum t, MyNum a1) {
t = a1;
t.setA(3);
}
}
public class MyNum {
public int a;
public MyNum(int b) {
this.a = b;
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
@Override
public String toString() {
return "MyNum [a=" + a + "]";
}
}
运行结果:
c = MyNum [a=1]
c1 = MyNum [a=3]
分析:
在Test1中c、c1的值分别赋值给两个形参(他俩的值是俩地址,c指向new MyNum(1),c2指向new MyNum(2),这里我简称区域1和区域2)。
当t= a1时,t指向指向区域2,当执行t.setA(3)时,区域2的值被修改为3。
当Test的生命周期结束时,两个形参t和a1所在栈创建的空间也被销毁。
但是他们被销毁前所指向的堆内的区域,依旧存在,他们对其做的修改,依旧有效。
当输出c和c1时,c和c1依旧分别指向区域1和区域2。输出也就是 1和3