Java是值传递还是引用传递?值传递!!!
今天在背八股文是遇到了一个问题,Java是值传递还是引用传递?我也以为基本数据类型是值传递,引用数据类型是引用传递。但答案告诉我不是这样的。颠覆了我的三观,打破了我的认知。网上的解释也是模糊不清(强行解释),看的我愈加认为我是对的。直到我有了自己的理解。
一、前言
开始之前我要告诉你们答案,Java参数的传递方式是值传递。我知道你不愿意接受这个事实,或者有着自己的理解,先别急着生气(心想又是一篇垃圾文章)。
我知道你很急,但是先不要急。
首先我们要知道什么是值传递和引用传递。
值传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
引用传递指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。
以上定义摘自百度百科,先理解定义。
二、基础数据类型验证
public class Main {
public static void main(String[] args) {
// 验证基础数据类型
int a = 1;
int b = 2;
basicDataTypes(a,b);
System.out.println("a = " +a);
System.out.println("b = " +b);
}
// 基础数据类型-> 值传递
private static void basicDataTypes(int a, int b) {
a=5;
b=6;
}
}
结果
这里在basicDataTypes函数中修改了a,b的值,但是实参a,b并没有改变。
所以基础数据类型是值传递。
三、引用数据类型(含顶级理解)
上才艺!!!
public class Main {
public static void main(String[] args) {
// 验证引用数据类型
Person p1 = new Person("zhangsan", 18);
Person p2 = new Person("lisi", 20);
referenceType(p1,p2);
System.out.println(p1);
System.out.println(p2);
}
// 引用数据类型-> 值传递
private static void referenceType(Person p1, Person p2) {
p1=new Person("wangwu",30);
p2.setAge(23);
}
public static class Person{
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public String name;
public Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
}
结果:
我们可以看到p1内容并没有变,这就已经说明引用类型是值传递,至少可以说明不是引用传递。
有人就会说p2的年龄变了啊,不满足上述值传递定义“在函数中如果对参数进行修改,将不会影响到实际参数。”
解答:
这里所说的 参数的修改 是对 形参的值 的修改,值的修改是否会影响到实参的值,并不是说对形参内容的修改,而去影响实参的内容。
因为Java中 引用对象的值传递 传递的是该对象地址的一个副本,并不是原对象本身。所以对形参对象进行内容上的修改会同时改变原对象。