背景
最近复习java相关的知识,看到有一个资料里写道:Java 中不存在引用传递。于是又看了一些帖子,有些说Java中只有值传递,而有些说二者都有;这难免让人感到疑惑,大概在这里总结一下。
基础知识
Java中,除基本类型外,其他类型都是以引用的方式传递变量。
值传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
引用传递中,形参实参指向同一个对象,形参的操作会改变实参对象。
对象的传递则和基本类型不同,传递的是该对象的一个引用,即指向对象的一个指针。也就是说,传递到方法中的对象和外部的对象是同一个对象,在方法内部对对象的修改,在方法外部会有所体现。
探究
定义Person类
public class Person {
public String name = "Person";
public int age = 20;
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
写定义测试类进行测试
public class Test {
public static void main(String[] args) {
Person p = new Person();
System.out.println("方法传递前Person为:" + p);
func(p);
System.out.println("方法传递后Person为:" + p);
}
public static void func(Person p) {
p.name = "被修改的名字";
}
}
运行结果
分析
传递到方法中的对象和方法外部的对象是同一个对象, 在方法内修改对象的属性,方法外的对象也会变化。那为什么会说Java中不存在引用传递呢?请看下面的例子
另一个例子
public class Test {
public static void main(String[] args) {
Person p = new Person();
System.out.println("方法传递前Person为:" + p);
func(p);
System.out.println("方法传递后Person为:" + p);
}
public static void func(Person p) {
p = new Person();
p.name = "被修改的名字";
}
}
运行结果
分析和结论
再看一下引用传递的定义:引用传递中,形参实参指向同一个对象,形参的操作会改变实参对象。
而在第二次的测试中,可以看到,在方法内对传入的引用的改变, 并没有在外部被体现出来。在函数内,传入的参数指向了另一个对象,但在方法外部外部,指向原对象的引用并没有跟着改变。
引用传递严格来说是C++中的概念,而Java中没有明确的定义。在C++ 中, 对象的传递可以通过 & 运算符直接将地址传递给函数,这意味着,如果在函数内将另外一个对象赋给了传入的参数,那么在函数外面仍然是可以被影响的到的。这也就是与Java中不同而引起争议的地方。
可以得出:中Java中确实不存在严格意义上的引用传递