java的参数传递机制和C、C++其实很像,前两天在改一个网站异步接口的时候,掉入坑里,之前是外包写的代码,springMVC里起了一个多线程,但是参数传递的时候传的是一个model对象,所以所有线程都共用了这个对象,结果跑出来的result一塌糊涂。
下面进入正题,先看一段demo代码吧
public class Model { private int value; public int getValue() { return value; } public void setValue(int value) { this.value = value; } } public class Demo { public static void main(String[] args) { String str = "str"; int i = 1; Model model = new Model(); model.setValue(1); Demo test = new Demo(); test.fun(str, i, model); System.out.println(str+"\t"+i+"\t"+model.getValue()); } public void fun(String str,int i,Model model){ str="fun_str"; i = 2; model.setValue(2); System.out.println(str+"\t"+i+"\t"+model.getValue()); } }
java中对于String,int,float等基本类型,都是值传递,所以结果如下
fun_str 2 2 str 1 2
String和int类型的值copy了一份传入函数,但是model对象的结果却是一样。由此可见,对象传递时是引用传递,想一想如果20个线程共用这一个对象,值肯定乱成一团。
就算函数里重新new一个对象也没用(下面代码),因为这么直接赋值也是引用,把model的地址赋给model2了,浅拷贝(指针引用)。
public void fun(String str,int i,Model model){ Model model2 = new Model(); model2 = model; str="fun_str"; i = 2; model2.setValue(2); System.out.println(str+"\t"+i+"\t"+model2.getValue()); }
要想实现深拷贝(内存中新new一个相同的对象),方法很多,可以把对象的值都取出来传参,如果太多可以放个map里,或者java应该有些对象clone的功能吧(下一期研究一下java的clone),如果没有就自己写个函数自己手动copy,new一个对象,把原来对象的东西都赋值到新对象中。