在 Java 中喷橙,方法的調(diào)用,只有值傳遞登舞。(不同于 C++)
也就是說參數(shù)無論是引用類型還是基本類型贰逾,傳過去的都是變量的副本,形參的操作菠秒,不影響原始內(nèi)容疙剑。
但是如果對引用類型對象成員變量的修改,是因?yàn)閷?shí)參和形參指向了同一個堆對象践叠,實(shí)參內(nèi)容(引用地址)并未修改言缤。
上文“方法的調(diào)用”可以推廣到 for 循環(huán)遍歷處理等。
代碼說明一切
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import com.alibaba.fastjson.JSON;
/**
* 印證 Java 只有值傳遞
* 方法傳遞的僅僅是引用的一個副本值
* @author duzhen.dz
* @since 2019-11-15
*/
public class TestChallenge {
public static void main(String args[]) throws InterruptedException {
User user1 = new User("user1");
User user2 = new User("user2");
System.out.println(System.identityHashCode(user1));
chalengeValue(user1);
System.out.println(user1);
System.out.println(System.identityHashCode(user1));
// 767010715
// User{name='user1'}
// 767010715
// 結(jié)論:形參的重新賦值未修改實(shí)參(地址)
System.out.println(System.identityHashCode(user2));
chalengeName(user2);
System.out.println(user2);
System.out.println(System.identityHashCode(user2));
// 110431793
// User{name='newUser'}
// 110431793
// 結(jié)論:形參的重新賦值未修改實(shí)參(地址)禁灼,僅僅修改了實(shí)參地址對應(yīng)的堆內(nèi)對象的成員變量
int a = 1;
chalengeValue(a);
System.out.println("a : " + a);
// a : 1
// 結(jié)論:形參的重新賦值未修改實(shí)參值
List<User> users = Arrays.asList(new User("user1"), new User("user2"));
for (User user : users) {
chalengeValue(user);
}
System.out.println(JSON.toJSONString(users));
// [{"name":"user1"},{"name":"user2"}]
// 結(jié)論:推廣至 for 循環(huán)遍歷調(diào)用
}
public static void chalengeValue(User user) {
User newUser = new User("newUser");
user = newUser;
}
public static void chalengeValue(int v) {
v = 2;
}
public static void chalengeName(User user) {
user.setName("newUser");
}
static class User {
private String name;
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}
}
參考文章
https://juejin.im/post/5bce68226fb9a05ce46a0476
https://blog.csdn.net/wuwenxiang91322/article/details/17038557
在Java中所有的參數(shù)傳遞管挟,不管基本類型還是引用類型,都是值傳遞匾二,或者說是副本傳遞哮独。只是在傳遞過程中:
如果是對基本數(shù)據(jù)類型的數(shù)據(jù)進(jìn)行操作,由于原始內(nèi)容和副本都是存儲實(shí)際值察藐,并且是在不同的棧區(qū),因此形參的操作舟扎,不影響原始內(nèi)容分飞。
如果是對引用類型的數(shù)據(jù)進(jìn)行操作,分兩種情況睹限,一種是形參和實(shí)參保持指向同一個對象地址譬猫,則形參的操作讯檐,會影響實(shí)參指向的對象的內(nèi)容。一種是形參被改動指向新的對象地址(如重新賦值引用)染服,則形參的操作别洪,不會影響實(shí)參指向的對象的內(nèi)容。