【JAVA基础-1】参数引用的理解

149 阅读3分钟
嘿,朋友。今天我们来说说JAVA中的参数传递。 直接上栗子
栗子1

main(){
 var a = new Obj(); a.setValue(1);
 var b = new Obj(); b.setValue(2);

 method_1(a,b);

 println("a的最后value="+a.getValue());
 println("b的最后value="+b.getValue());
} 


method_1(obj a, obj b){
    a.setValue(13);
    b.setValue(23);
}

栗子1最终的输出结果:
a的最后value=13
b的最后value=23


栗子2

main(){
 var a = new Obj(); a.setValue(1);
 var b = new Obj(); b.setValue(2);
 
method_2(a,b);

println("a的最后value="+a.getValue());
println("b的最后value="+b.getValue());}

 method_2(obj a, obj b){
    var temp = new Obj();
    temp = a;
    a = b;
    b = temp;
}


栗子2最终的输出结果:
a的最后value=1
b的最后value=2

在JAVA的参数传递中,分为值传递和引用传递。

值传递比较通俗易懂,即传递的是实际值,被传递的参数在方法体中的任何修改都不会影响方法体外的对应变量。基本数据类型和String都属于这种。


而引用传递就有一点点绕了。引用传递根据字面意思,即传递的是引用地址。

被传递的参数在方法体内的对属性进行修改会影响方法体外的对应变量,比如例子1的代码。


而例子2,则是更绕一点了,通过例子1,我们会形成这样的理解,参数传递对象时即为引用传递,那么传递就是对象的引用地址。那么例子2也应该是引用传递。

但通过method_2的执行后,理论上应该交换了a和b的value值,但输出结果并没有。

根据《JAVA核心技术卷I》所述,对象的传递本质是传递对象引用的副本,当方法体执行结束,引用地址的副本也随之销毁。

根据这句话,我们重新理解上面两个例子

例子1中,在mehtod_1中传递的是ab对象引用地址的副本,引用地址副本与方法体外的对象一致,所以在mehtod_1方法体中,修改对ab副本的value即改变了方法体外的ab对象的value。因为:

a副本与方法体外的a对象引用地址一致

b副本与方法体外的b对象引用地址一致


例子2中,同样mehtod_2传递的是ab对象引用地址的副本,mehtod_2方法体中交换的只是ab的副本,与mehtod_2方法体外的ab对象无关,所以最后输出结果并没有交换ab的value值。


根据《JAVA核心技术卷I》的结论,方法参数有三点谨记:

1.方法无法改动基本数据类型的参数。

2.方法可以改变对象参数的属性

3.方法不能让一个对象参数引用有一个新对象


留个小问题:


main(){
 var a = new Obj(); a.setValue(1);
 var b = new Obj(); b.setValue(2);

    method_3(a,b);

println("a的最后value="+a.getValue());
println("b的最后value="+b.getValue());
}

 method_3(obj a, obj b){
    var temp = new Obj();
    temp = a;
    a = b;
    b = temp;
    a.setValue(13);
    b.setValue(23);}

最后会输出什么.....?