首先,寫一段程序,分析程序執(zhí)行的過程中,堆棧空間的開辟、空間內(nèi)數(shù)據(jù)的寫入和垃圾空間的回收。
上代碼

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();
}
}
程序運行結(jié)果為:
分析程序執(zhí)行過程:
創(chuàng)建Person類,屬性有name和age,構(gòu)建一個say方法:打印姓名和年齡。
然后逐句分析Demo01運行過程,及運行過程中堆棧內(nèi)存的開辟、寫入數(shù)據(jù)和回收。
Person p1 = new Person(); //在棧內(nèi)存中開辟p1,然后用new關(guān)鍵字創(chuàng)建對象,
//也就是在對內(nèi)存中開辟p1所指向的堆內(nèi)存空間。
Person p2 = new Person(); //在棧內(nèi)存中開辟p2,然后用new關(guān)鍵字創(chuàng)建對象,
//也就是在對內(nèi)存中開辟p2所指向的堆內(nèi)存空間。
此時的堆棧內(nèi)存:
接下來的四句話為:
p1.name = "張三";
p1.age = 20;
p2.name = "李四";
p2.age = 30;
此時的堆棧內(nèi)存為:
最后對p1、p2執(zhí)行say方法,結(jié)果為:
若把程序改一下,加上一句話:p2 = p1;
程序變?yōu)椋?/p>

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();
}
}
再執(zhí)行:
執(zhí)行加入的語句之前不變,堆棧空間也和加之前相同,當(dāng)執(zhí)行加入的語句之后,
堆棧內(nèi)存為:
此時棧內(nèi)存p2指向p1所指向的堆內(nèi)存空間,而p2之前指向的堆內(nèi)存空間已經(jīng)沒有了棧內(nèi)存的指向,
因此成為垃圾,就會被回收掉,堆棧內(nèi)存變?yōu)椋?/p>
再執(zhí)行下面兩句,為p1指向的堆內(nèi)存空間賦值,由于p1、p2指向同一塊堆內(nèi)存,也就相當(dāng)于為p2
指向的堆內(nèi)存空間賦值,堆棧內(nèi)存變?yōu)椋?/p>
再執(zhí)行下面兩句,為p2指向的堆內(nèi)存空間賦值,由于p1、p2指向同一塊堆內(nèi)存,也就相當(dāng)于為
p1指向的堆棧內(nèi)存空間重新賦值,堆棧內(nèi)存變?yōu)椋?/p>
我們可以看到,棧內(nèi)存p1、p2所指向的同一塊堆內(nèi)存中的數(shù)據(jù)改變了,然后執(zhí)行下面的say方法,
執(zhí)行結(jié)果為:
為什么兩句結(jié)果相同呢?因為是程序按語句的順序執(zhí)行,先改變堆內(nèi)存的數(shù)據(jù),后執(zhí)行的say方法,
所以兩句結(jié)果相同。
若把程序再改一下,把 p1.say(); 提前
程序變?yōu)椋?/p>

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();
}
}
執(zhí)行語句 p1.say(); 之前,堆棧內(nèi)存為:
執(zhí)行 p1.say(); 對堆棧內(nèi)存沒有影響,只是輸出此時p1所指向的堆內(nèi)存中的數(shù)據(jù):
輸出:
,然后繼續(xù)執(zhí)行下面的語句。
執(zhí)行p2.name = "李四"; p2.age = 30;
為p2指向的堆內(nèi)存空間賦值,由于p1、p2指向同一塊堆內(nèi)存,也就相當(dāng)于為
p1指向的堆棧內(nèi)存空間重新賦值,堆棧內(nèi)存變?yōu)椋?/p>
然后執(zhí)行 2.say(); 輸出棧內(nèi)存 p2 指向的對內(nèi)存中的數(shù)據(jù):“姓名:李四, 年齡:30”
完整的程序執(zhí)行完后,輸出結(jié)果為:

總結(jié):
語句的排列順序不同,程序執(zhí)行的結(jié)果也不同。
posted on 2010-10-12 02:55
Mineralwasser 閱讀(246)
評論(0) 編輯 收藏