Java中参数的传送方式只有值传递,没有引用传递
看以前的学习资料的时候突然发现之前写了这么一篇技术博客,写的很水希望各位大牛勿喷。
值传递:就是开辟一个新的空间,把原来的空间中所以的内容复制到新的空间中,而改变新的值不影响原来的值的改变。比如变量A传递给变量B,A对应的是堆C中存储的数据,如果为值传递则在堆中开辟一块新的内存D,把堆C中的内容复制到D之中,改变B就是改变D中存储的数据与A无关。
引用传递:我理解起来感觉这个更像是一种内存空间的传递,就是传递给新的变量指向的还是原来的内存空间,改变新变量的值也就是改变原来变量的值。比如变量A传递给变量B,A对应的是堆C中存储的数据,则B通过线2指向A对应的堆C中的数据空间,修改B也等于修改A的堆中的数据。
那么JAVA中参数的传递到底是值传递还是引用传递呢?让我们看下面这一段代码。
//测试类
package test;
publicclass test {
privatestaticinta=5;
privatestatic String str="hello";
public staticvoid main(String args[]){
test t=new test();
System.out.println("before change "+str);
t.motifyStr(str);
System.out.println("after change "+str);
System.out.println("before change "+a);
t.motifyInt(a);
System.out.println("after change "+a);
}
publicvoid motifyStr(String tochange){
tochange="hi";
}
publicvoid motifyInt(int b){
b=10;
}
}
测试的结果为:
before change hello
after change hello
before change 5
after change 5
也就是说java中基本类型的参数传递是值传递。那么自定义类型又是什么情况呢?
package test;
//自定义学生类
publicclass Student {
String name;
intage;
public Student(String name){
this.name=name;
}
publicvoid setname(String name){
this.name=name;
}
}
//测试类
package test;
publicclass test1 {
privatestatic Student stu=new Student("毛杰");
publicstaticvoid main(String args[]){
test1 t=new test1();
System.out.println("beforechange "+stu.name);
t.modifystu(stu);
System.out.println("afterchange "+stu.name);
}
publicvoid modifystu(Student stu){
Student stu1=new Student("毛文杰");
stu=stu1;
System.out.println("rightnow "+stu.name);
}
}
结果为:
beforechange 毛杰
rightnow 毛文杰
afterchange 毛杰
也就是说在java中无论是基本类型还是自定义类型的参数传递都是通过值传递的。也就是图中A作为实参传到B中而B相应的在堆中开辟了一个新的内存块D来复制C中的内容,B的改变并不影响A。
既然说到了参数传递,那进一步我们来探讨基本类型和自定义类型赋值的区别是值传递还是引用传递。
首先我们来测试一下自定义类型:
package test;
publicclass test2 {
privatestatic Student stu=new Student("毛杰");
privatestatic Student stu1=new Student("毛文杰");
publicstaticvoid main(String args[]){
System.out.println(stu.name);
System.out.println(stu1.name);
stu=stu1;
System.out.println(stu.name);
System.out.println(stu1.name);
stu.setname("毛杰文");
System.out.println(stu.name);
System.out.println(stu1.name);
stu1.setname("毛小杰");
System.out.println(stu.name);
System.out.println(stu1.name);
}
}
结果为:
毛杰
毛文杰
毛文杰
毛文杰
毛杰文
毛杰文
毛小杰
毛小杰
说明在赋值的过程中,自定义类型是引用传递的,用图中的示例来说,也就是说把A的值赋值给B等于让B指向A在堆中对应的C的内存空间,A和B的改变都会造成堆中C里面存储数据的改变。
那么基本类型又是什么情况呢?
package test;
publicclass test3 {
privatestaticinta=5;
privatestaticintb=10;
privatestatic String str="hello";
privatestatic String str1="hi";
publicstaticvoid main(String args[]){
System.out.println("a:"+a);
System.out.println("b:"+b);
b=a;
System.out.println("after b=a b:"+b);
b=12;
System.out.println("a:"+a);
System.out.println("b:"+b);
System.out.println("str:"+str);
System.out.println("str1:"+str1);
str1=str;
str1="你好";
System.out.println("str:"+str);
System.out.println("str1:"+str1);
}
}
结果是:
a:5
b:10
after b=a b:5
a:5
b:12
str:hello
str1:hi
str:hello
str1:你好
说明在赋值过程中基本类型是值传递,就是新开辟一个内存来复制赋值内容,改变传递后的变量对被赋值变量无影响。