源代码:
classPerson
{
private String name;
private int age;
//构造函数
Person(String name)
{
this.name=name;
System.out.println("name=name");
}
public void speak()
{
System.out.println("name:"+name);
}
}
publicclass ThisDemo
{
public static void main(String args[])
{
Person p=newPerson("LIMING");
p.speak();
}
}
1.执行主函数main,p变量进栈,堆内存中产生对象,成员变量name,age初始化,name=null,age=0,堆内存中对象获取地址0x0045(如图1)。
2.在Person p=new Person(“LIMING”);中,初始化完成之后开始执行new Person(“LIMING”),这个对象调用构造函数Person(Stringname){}(如图2)此时构造函数Person进栈。此时将”旺财”赋给构造函数里的name,name=”旺财“。(如图3,图4)
3.构造函数是给对象初始化,构造函数一定是被对象 调用的。被对象调用的构造函数,它是在访问对象中的这个name,但是它给哪个对象初始化时不确定的。方式被对象调用的方法它们里面都有一个东西:this的引用。这个方法要给哪个对象初始化呢,也就是说,哪个对象调用我,我就给哪个对象初始化。This持有一个对象,this指向哪个对象就给哪个对象初始化。This有一个自己的引用持有。当这个对象一调用Person()进入内存的时候,这个this立刻就有值了,这个值就是地址0x0045,这个是这个this就 指向了这个对象new Person(){}(如图5)
4.接着执行构造函数Person(){}里的语句{this.name=name;}如图5,将name的值赋给this.name,name=”旺财“就赋给0x0045所指向的对象中的name,此时,”旺财“覆盖掉this所指向对象中的name的空值。(如图6)
5.这个是构造函数执行完毕,从栈内存中弹了出来。进行弹栈。(如图7)
6.此时,将右边的值newPerson(“旺财”)赋给左边,即:最后将地址0x0045赋给p变量,p指向了堆中的对象。(如图8)。实例化变量这个时候才真正的初始化完毕。
7.这个时候speak(),开始进栈。哪个对象在调用speak(),p对象在调用speak(),是p的地址(0x0045)所引用的实体。所以speak()里面也有一个this。这个时候对象就把值(0x0045)赋给了this(如图9)。
完了之后,this就指向了对象。(如图10)
8.speak()函数开始执行它里面的函数,{System.out.println(name+” ”+age);},在这个输出语句里,它里面全都省略了this.name,this.age,这样的形式。这是为什么呢?因为:因为在speak()这个方法里并没有定义过name,age这样的局部变量。所以它访问的全是成员的变量(类里面的成员变量),即对象里面的变量(没有重名的话可以不加this)。这样的话,通过this访问对象,分别输出this.name;this.age的值。然后speak()弹栈。(如图11).