首先,寫一段程序,分析程序執行的過程中,堆棧空間的開辟、空間內數據的寫入和垃圾空間的回收。
上代碼

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();
}
}
再執行:
執行加入的語句之前不變,堆??臻g也和加之前相同,當執行加入的語句之后,
堆棧內存為:
此時棧內存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 閱讀(246)
評論(0) 編輯 收藏