标签:ref 而不是 按引用传递 按值传递 简单 ack 小问题 nbsp 传引用
这是个老生常谈的问题了,引起过无数争论,但可以说一直没有一个令人满意的回答。
有人总结过:
简单总结:
在开源中国看到这样一则问题:
https://www.oschina.net/question/2507499_2244027,其中的变量a前后的输出是什么?
我答错了,我认为传入function的就是main函数中的a,在function中修改了a的地址,因此回到主函数后,a的地址已经变成了function中所赋予的a2的地址,因此经过function处理后a的值已经改变了。 但结果并不是,因为我忽略了Java的基础知识点之一:Java中传参都是值传递,如果是基本类型,就是对值的拷贝,如果是对象,就是对引用地址的拷贝。
以下是处理类Porcess,代码应该已经能够自解释了。function1是将传参a变成2,function2是初始化int b,赋值为5,然后将b赋值给a:
public class Process { public void function1(int a) { a = 2; } public void function2(int a) { int b = 5; a = b; } }
我们继续看测试类TestPrimitive:
public class TestPrimitive { public static void main(String[] args) { Process process = new Process(); int age = 18; System.out.println(age); process.function1(age); System.out.println(age); } }
经过function1处理后,结果是:
18 18
修改测试类,经过function2处理后,结果是:
18 18
结论:基本类型传参,对传参进行修改,不影响原本参数的值。
以下是处理类Porcess,function3,将参数car的颜色设置成blue。function4,新建了car2,将car2赋值给了参数car。
public class Process { public void function3(Car car) { car.setColor("blue"); } public void function4(Car car) { Car car2 = new Car("black"); car = car2; car.setColor("orange"); } }
我们继续看测试类TestReference
public class TestReference { public static void main(String[] args) { Process process = new Process(); Car car = new Car("red"); System.out.println(car); process.function3(car); System.out.println(car); } }
结果是在经过function3的处理后,输出结果是:
Car{color=‘red‘}
Car{color=‘blue‘}
修改测试类,在经过function4的处理后:
Car{color=‘red‘}
Car{color=‘red‘}
结论: 对象类型的传参,直接调用传参set方法,可以对原本参数进行修改。如果修改传参的指向地址,调用传参的set方法,无法对原本参数的值进行修改。
综上所述,基本类型的传参,在方法内部是值拷贝,有一个新的局部变量得到这个值,对这个局部变量的修改不影响原来的参数。对象类型的传参,传递的是堆上的地址,在方法内部是有一个新的局部变量得到引用地址的拷贝,对该局部变量的操作,影响的是同一块地址,因此原本的参数也会受影响,反之,若修改局部变量的引用地址,则不会对原本的参数产生任何可能的影响。
标签:ref 而不是 按引用传递 按值传递 简单 ack 小问题 nbsp 传引用
原文地址:http://www.cnblogs.com/cb0327/p/7278892.html