目录
【导语】面试官到底想考什么?
一、值传递和引用传递的本质区别
1. 值传递(Pass by Value)
2. 引用传递(Pass by Reference)
二、Java的“值传递”真相:传的是引用的副本
1. 基本类型:直接拷贝值
2. 对象类型:传递引用的副本
三、常见误区:别再踩这些坑!
误区1:“对象是引用传递”
误区2:“数组是引用传递”
误区3:“String是特殊引用传递”
四、实战案例:覆盖90%的应用场景
案例1:对象属性修改
案例2:集合类修改
案例3:数组扩容
五、总结:记住这几点!
六、进阶思考:为什么Java不做引用传递?
面试时一问“Java是值传递还是引用传递”,很多人就开始背标准答案:“基本类型值传递,对象引用传递”。但真相是——Java只有值传递,没有引用传递! 本文带你彻底搞懂本质,附代码案例和常见误区解析。
public void increment(int a) {
a += 1; // 修改的是副本
}
int b = 5;
increment(b);
System.out.println(b); // 输出5,原值不变
public void modify(Object obj) {
obj = new Object(); // 修改地址指向
}
Object o = new Object();
modify(o);
// 如果Java支持引用传递,o会被修改,但实际并非如此
public void swap(int x, int y) {
int temp = x;
x = y;
y = temp;
}
int a = 1, b = 2;
swap(a, b);
System.out.println("a=" + a + ", b=" + b); // 输出a=1, b=2
public void changeName(User user) {
user.name = "New Name"; // 修改对象属性
user = new User("Other"); // 重新赋值(不影响原对象)
}
User u = new User("Original");
changeName(u);
System.out.println(u.name); // 输出"New Name"
user
和u
都指向堆中同一对象)。name
)会同步到原对象。user
只会改变副本的指向,原对象不受影响。public void modifyArray(int[] arr) {
arr[0] = 100; // 修改数组元素
arr = new int[]{2, 3}; // 重新赋值(不影响原数组)
}
int[] scores = {50, 60};
modifyArray(scores);
System.out.println(Arrays.toString(scores)); // 输出[100, 60]
arr
不会改变scores
的指向。public void changeString(String s) {
s = "New String"; // 无效!字符串不可变且传递的是副本
}
String str = "Hello";
changeString(str);
System.out.println(str); // 仍输出"Hello"
class Person {
String name;
}
public void resetName(Person p) {
p.name = "Anonymous"; // 原对象被修改
}
Person person = new Person("Alice");
resetName(person);
System.out.println(person.name); // 输出"Anonymous"
public void addElement(List list) {
list.add(3); // 修改原列表
list = new ArrayList<>(); // 不影响原列表
}
List myList = new ArrayList<>(Arrays.asList(1, 2));
addElement(myList);
System.out.println(myList); // 输出[1, 2, 3]
public void resizeArray(int[] arr) {
arr = Arrays.copyOf(arr, arr.length + 1); // 仅修改副本指向
}
int[] nums = {1, 2, 3};
resizeArray(nums);
System.out.println(nums.length); // 仍为3