1.基本数据类型传递参数
public class Test {
public static void main(String[] args) {
int i = 1;
Test t = new Test();
t.test1(i);
System.out.println(i);
}
public void test1(int a){
a = 100;
}
}
此时输出1,也就是说test方法并没有改变i的值;
内存过程分析:调用test方法时,系统为形参分配一块栈内存,并将i的值复制到栈内存中;然后test方法将新分配的内存中的数值改变,程序执行结束后,这块新分配的内存会被回收,而i原本所在的内存自始至终都没有变化。
2.引用数据类型参数传递
public class Date {
int day;
int month;
int year;
public Date(int year,int month,int day){
this.day = day;
this.month = month;
this.year = year;
}
public void setDay(int day){
this.day = day ;
}
public int getDay(int day){
return this.day;
}
public void setMonth(int month){
this.month = month ;
}
public int getMonth(int month){
return this.month;
}
public void setYear(int year){
this.year = year ;
}
public int getYear(int year){
return this.year;
}
public void print() {
System.out.println(this.year + "-" + this.month + "-" + this.day);
}
}
public class Test {
public static void main(String[] args) {
Test t = new Test();
Date d = new Date(2005,4,25);
System.out.println("调用前");
d.print();
t.test1(d);
System.out.println("调用后");
d.print();
}
public void test1(Date d){
d = new Date(2020,4,25);
}
}
调用前和调用后都是输出2005-4-25,说明test1方法没有改变参数值。
过程分析:调用test1时,系统为传递进去的形参分配一块栈内存,并将d中的内容复制到新的栈内存中,也就是将Date(2005,4,25)的地址复制给新的栈内存。此时,新的栈内存和之前的引用数据类型变量d都指向同一块堆内存Date(2005,4,25)。在test1方法中,new方法会在堆内存中开辟一块新的内存,并将新的栈内存中的地址改为这块新的堆内存的地址。程序执行结束后,新开辟的内存地址都会被回收,原先的栈内存还是存储的之前的堆内存的地址,因此没有变化。
public void test1(Date d){
d.setDay(15);
}
将test1函数改变,输出了2005-4-15。
过程分析:系统为形式参数d分配了新的栈内存,指向堆内存中的Date(2005,4,25),此时调用了setDay方法,改变了堆内存中day的值,而不是开辟一块新的堆内存,所以即使新的栈内存在程序结束后被回收,之前的栈内存指向的堆内存的内容被改变了。
参考博客:
https://blog.csdn.net/Myuhua/article/details/81358393?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task