虽然经常听说Java当中只有值传递,但我还是更愿意将他们分为两种,一种是值传递,一种是引用传递。
先来看一段代码,看看程序的运行结果,再来依次分析问题所在
Person类
/**
* @author: xuzhi
* @date: 2020/10/14 12:06
*/
public class Person {
private int id;
private String name;
public Person() {
}
public Person(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
/**
* 测试Java中的值传递和引用传递
*/
public class Test {
public void changeValue1(int age){
age=30;
}
public void changeValue2(Person person){
person.setName("笨蛋");
}
public void changeValue3(String str){
str="XXX";
}
public static void main(String[] args) {
Test test=new Test();
int age=18;
test.changeValue1(age);
System.out.println("age--->"+age);
Person person=new Person(1,"xuzhi");
test.changeValue2(person);
System.out.println("personName-->"+person.getName());
String str="xuzhi";
test.changeValue3(str);
System.out.println("str-->"+str);
}
}
程序运行结果如下
我们来依次看一下
1、基本数据类型
基本数据类型传递的是变量的副本,changeValue1(int age)方法中只是对副本进行了修改,并且这个age是一个局部变量,只在当前方法里有效。
了解JVM内存模型,你会知道,每调用一个方法就会在栈中开辟一小块的内存空间,这部分空间叫做栈帧
我们打印的是main方法中age的值,并不是changeValue1方法中的age值
2、引用数据类型
还是从JVM内存模型的角度去分析,main方法和changeValue2方法中指向的是堆上同一个person对象
3、字符串类型
由于字符串类型的特殊性,在给字符串重新赋值的时候,它先会去常量池中查找,有就指向它,没有就会重新创建一个。