在C语言中,如果函数的形参是指针类型,那么在函数体中,修改该形参,实参也会产生相应变化
在Java中,由于类的实例化在堆中完成,方法的形参在栈中创建,这时会产生一种新手常见的错误(可能理解的不透彻,欢迎讨论)
先看下面一段代码
import javafx.scene.shape.Circle;
public class ClassTest {
public static void main(String[] args) {
ClassTest classTest = new ClassTest();
classTest.first();
}
void first(){
Data data1 = new Data();
data1.m = 10;
System.out.println("最初的data1.m值"+ data1.m);//此时输出结果为5
second(data1,5);//调用第二个方法,希望修改当前的data1.m的值
System.out.println("调用second方法后的data1.m值" + data1.m);//此时期望的输出结果为0,但实际输出还是5
}
void second(Data data2, int i){
data2.m = i;//修改传入的Data类的实例化对象的m值
System.out.println("通过形参i修改形参data2.m的值" + data2.m);//输出结果预期为5,实际也为5
Data newData = new Data();
data2 = newData;//希望将传入的对象覆盖为一个默认的初始化对象,期望此时first方法中的data1.m为0,实际输出仍为5
}
}
class Data{
int m;//int型属性若不初始化,默认值为0
}
输出的结果如下
我们预期的调用second方法后的data1.m值为0,可是为什么最终的输出结果为5呢?
我们在堆栈中对代码运行的步骤进行详解
首先实例化了一个classTest,在堆栈中的状况如下图:
接着在first方法中实例化了一个data1并将属性m赋值,在堆栈中的状况如下:
然后在first方法中调用second方法,first方法中的data1作为second方法中data2形参的实参,此时data2指向的内容与data1一致,并通过形参i对data2指向的内容进行修改:
之后在second方法中又new了一个newData的类,并让data2指向newData类中的内容:
经过我们对代码运行时堆栈空间的理解,不难发现,在调用second方法时,栈空间会重新生成一个data2(形参)来指向实参的内容,通过后续对data2的指向位置的修改,并不影响data1的指向。