构造函数里的变量的内存图解
源代码:
class Person
{
private String name;
private int age;
Person(String n,int a)
{
this.name=n;
this.age=a;
}
public void speak()
{
System.out.println(name+","+age);
}
}
public classPersonTest
{
public static void main(String args[])
{
Person p2=new Person("小强",10);
p2.speak();
}
}
1. 首先主函数先进栈,然后在栈里出现一个p2(对象的实例化变量)。(图1)
2.接着在堆空间里产生一个对象,为其分配一片空间,首地址值为0x0045,实例化的对象一产生堆空间里有一个变量name,age,这些对象都有默认初始化值:name=null;age=0;此时对象创建完毕。(图2)
3.对象进行默认初始化完成之后,这个对象应该去找构造函数,因为如果对象没有调用构造函数的话,就相当于对象没有创建成功,(对象只有初始化之后才能使用:这个对象的初始化除了有默认的初始化之外,还有构造函数的初始化)。
4.此时开始调用构造函数Person(String name,int age){this.name=n;this.age=a;},这个时候程序就执行到了这个构造函数这儿,构造函数开始进栈(构造函数是函数,所以函数进栈)。Person(String n,int a)开始进栈,里面还有变量n= a= 。(如图3)
5.此时只要调用了构造函数,变量“小强”,“10”就分别赋给了n和a,n就是小强,a就是10 :n=”小强”;a=10;(如图4)
6.这个时候构造函数开始执行语句{this .name=n;this.age=a;}。但是这个时候栈里面并没有name和age,所以应该到堆里面找。因为p2对象访问方法Person(),所以方法里的变量访问对象里的变量。通过this 来访问。哪个对象调这个方法,就将这个方法里 的值赋给这个对象。此时:就将“小强”赋给name;将10赋给了age;(如图5)
7.此时,栈里的构造函数Person(n,a)开始弹栈。函数及函数里的变量已经从栈里退了出来。(如图6)
8.接下来将对象p2的地址0x0045赋给了变量p2。(如图7)。这个时候对象的初始化才完成。
9.开始执行第二句语句p2.speak();speak(),是一个函数,这个时候speak()函数进栈,speak()是打印出“小强”和“10”。Speak()里的name和age开始访问堆里的变量name,age所对应的值。(如图8),最后speak()开始弹栈。
10.整个过程执行完毕。(如图9)