为什么说Java只有值传递,而没有引用传递?
误区
很多Java开发者可能理解的Java的值传递和引用传递是下面这样的。
void main(){
//值传递测试,输出a的值仍然是1
int a = 1;
passValue(a);
System.out.println(a);
//引用传递测试,输出的student.name已经改变
Studetn s= new Student();
s.setName("张三");
passRef(s);
System.out.println(s.getName());
}
//值传递
void passValue(int a){
a = 2;
}
//引用传递
void passRef(Student s){
s.setName("李四");
}
对上面的简单解释的就是:
passValue
传递的内容是值类型,所以是值传递passRef
传递的内容是Student类型,也就是引用类型,所以是引用传递
这是概念理解错误!!!
值传递和引用传递
接下来明确以下值传递与引用传递的概念:
值传递
- 形参会被分配独立的存储空间,用来拷贝存储实参。
- 对于形参的修改,不会影响实参。
引用传递
- 形参不分配独立的存储空间。
- 对于形参的修改,会影响实参。
- 相当于实参的别名。
解惑
看到这里,有人可能问了,上面的代码中 passRef
方法中,确实影响了main
中Student
对象的值了,这不就是引用传递吗?
其实不然,我们纠正一个错误认识: passRef
的形参是什么? 是参数s
,那么真正测试修改形参应该的代码应该如下:
void passRef(Student s){
s = new Student();
}
只有s本身被修改了,才算是修改了形参。
C++中的引用传递
我们可以看看真正的引用传递,例如C++中,
//引用传递
void passRef(int& a){
a = 20;
}
//值传递
void passValue(int a ){
a = 20;
}
void main(){
int a = 10;
passValue(a);
printf("%d",a);//不会改变a的值
passRef(a);
printf("%d",a);//该变了a的值
}