![](https://s2.loli.net/2022/01/20/uzLWtQ8qdYMoT57.jpg)
Java值传递与引用传递
Java中参数传递的方式
结论
Java 中只存在值传递
值传递
public class PassByValue {
public static void main(String[] args) {
int mainNum = 1;
passByValue(mainNum);
System.out.println(String.format("mainNum: %d", mainNum));
}
public static void passByValue(int num) {
num = 2;
System.out.println(String.format("num: %d", num));
}
}
结果:
num: 2
mainNum: 1
引用传递
public class PassByReference {
static class Person {
public Person(String name) {
this.name = name;
}
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public static void main(String[] args) {
Person person = new Person("rmrf2020");
passByReference(person);
System.out.println(String.format("personName: %s", person.getName()));
}
public static void passByReference(Person person) {
person.setName("I changed my Name");
System.out.println(String.format("changedPersonName: %s", person.getName()));
}
}
结果:
changedPersonName: I changed my Name
personName: I changed my Name
引用传递 or 值传递
上面两个例子,将引用传递和值传递的特性都表现出来了,可能有人会说:”基本类型用的是值传递,对象使用引用传递“。这样想的朋友可以看一下下面这个例子,这个例子我就不贴结果了,自己试一下才会记忆深刻
public class StringPassType {
public static void main(String[] args) {
String s = "s";
stringPassType(s);
System.out.println(String.format("personName: %s", s));
}
public static void stringPassType(String changedS) {
changedS = "I was changed!";
System.out.println(String.format("personName: %s", changedS));
}
}
上面这个例子看完了,发现传递对象类型也是“值传递”,显然不符合推测的“基本类型用的是值传递,对象使用引用传递”。
实际上在 Java 中只有值传递。
在 Java 中,String
类是不可变对象,因为它的修饰符是final
,既然上面这个例子的结果changeS
和s
输出内容不一致,那么它们的地址肯定也不一致。
实际上s
传递的是"s"
的地址,changedS
指向的也是"s"
的地址,当changedS = "I was changed!";
语句执行时,只是将changedS
指向"I was changed!"
的地址,而s
指向的内存地址是没有改变的。
在 IDEA 上也能看出一下差别
IDEA会提示我们将changedS修改为本地变量,因为它是否是传递过来的其实没有任何影响。
结合 @Hollis 的图理解,效果更佳。