首先,写一段程序,分析程序执行的过程中,堆栈空间的开辟、空间内数据的写入和垃圾空间的回收。
上代码
Personclass Person {
int age;
String name;
void say(){
System.out.println("姓名:"+name+", 年龄:"+age);
}
}
Demo01public class Demo01 {
public static void main(String[] args) {
Person p1 = new Person();
Person p2 = new Person();
p1.name = "张三";
p1.age = 20;
p2.name = "李四";
p2.age = 30;
p1.say();
p2.say();
}
}
程序运行结果为:
分析程序执行过程:
创建Person类,属性有name和age,构建一个say方法:打印姓名和年龄。
然后逐句分析Demo01运行过程,及运行过程中堆栈内存的开辟、写入数据和回收。
Person p1 = new Person(); //在栈内存中开辟p1,然后用new关键字创建对象,
//也就是在对内存中开辟p1所指向的堆内存空间。
Person p2 = new Person(); //在栈内存中开辟p2,然后用new关键字创建对象,
//也就是在对内存中开辟p2所指向的堆内存空间。
此时的堆栈内存:
接下来的四句话为:
p1.name = "张三";
p1.age = 20;
p2.name = "李四";
p2.age = 30;
此时的堆栈内存为:
最后对p1、p2执行say方法,结果为:
若把程序改一下,加上一句话:p2 = p1;
程序变为:
Demo01public class Demo01 {
public static void main(String[] args) {
Person p1 = new Person();
Person p2 = new Person();
//*******************************
p2 = p1;
//*******************************
p1.name = "张三";
p1.age = 20;
p2.name = "李四";
p2.age = 30;
p1.say();
p2.say();
}
}
再执行:
执行加入的语句之前不变,堆栈空间也和加之前相同,当执行加入的语句之后,
堆栈内存为:
此时栈内存p2指向p1所指向的堆内存空间,而p2之前指向的堆内存空间已经没有了栈内存的指向,
因此成为垃圾,就会被回收掉,堆栈内存变为:
再执行下面两句,为p1指向的堆内存空间赋值,由于p1、p2指向同一块堆内存,也就相当于为p2
指向的堆内存空间赋值,堆栈内存变为:
再执行下面两句,为p2指向的堆内存空间赋值,由于p1、p2指向同一块堆内存,也就相当于为
p1指向的堆栈内存空间重新赋值,堆栈内存变为:
我们可以看到,栈内存p1、p2所指向的同一块堆内存中的数据改变了,然后执行下面的say方法,
执行结果为:
为什么两句结果相同呢?因为是程序按语句的顺序执行,先改变堆内存的数据,后执行的say方法,
所以两句结果相同。
若把程序再改一下,把 p1.say(); 提前
程序变为:
Demo01public class Demo01 {
public static void main(String[] args) {
Person p1 = new Person();
Person p2 = new Person();
//*******************************
p2 = p1;
//*******************************
p1.name = "张三";
p1.age = 20;
p1.say();//位置提前到这里
p2.name = "李四";
p2.age = 30;
p2.say();
}
}
执行语句 p1.say(); 之前,堆栈内存为:
执行 p1.say(); 对堆栈内存没有影响,只是输出此时p1所指向的堆内存中的数据:
输出: ,然后继续执行下面的语句。
执行p2.name = "李四"; p2.age = 30;
为p2指向的堆内存空间赋值,由于p1、p2指向同一块堆内存,也就相当于为
p1指向的堆栈内存空间重新赋值,堆栈内存变为:
然后执行 2.say(); 输出栈内存 p2 指向的对内存中的数据:“姓名:李四, 年龄:30”
完整的程序执行完后,输出结果为:
总结:
语句的排列顺序不同,程序执行的结果也不同。
posted on 2010-10-12 02:55
Mineralwasser 阅读(244)
评论(0) 编辑 收藏