在對(duì)象指向中,我們一定要清楚引用類型數(shù)據(jù)的堆棧二段式內(nèi)存管理,下面通過(guò)一個(gè)小例子,讓我們來(lái)解析堆棧內(nèi)存是如何使用的。
先附一段代碼:

class People{
 public String name;
 public int age;
 public void say(){
  System.out.println("姓名:"+name+"  年齡:"+age);
 }
}
public class Test16 {

 public static void main(String[] args) throws InterruptedException {
  People p1 =new People();
  People p2 =new People();
  p1=p2;
  p1.name="大雨";
  p1.age=21;
  p1.say();
  p2.name="狗生";
  p2.age=22;
  p2.say();
 }
}

運(yùn)行結(jié)果如下圖:


這是為什么呢,其實(shí)是對(duì)象引用的問(wèn)題。

先看這個(gè)例子,里面先new了兩個(gè)對(duì)象,分別問(wèn)p1和p2,然后將p2的值附給了p1,這時(shí),p1的指向就發(fā)生了變化:p1就不再指向原來(lái)的地址了,此時(shí)p1就指向了p2所指向的地址了,也就是說(shuō):p1和p2指向了同一塊堆內(nèi)存。這時(shí)先給p1的屬性賦值,并且調(diào)用了p1的say方法,這個(gè)時(shí)候控制臺(tái)就打印出來(lái)p1所指向的堆地址(實(shí)際此時(shí)p2指向的也是這個(gè)堆地址);然后又給p2的屬性賦值,并且調(diào)用了p2的say方法,這個(gè)時(shí)候控制臺(tái)就會(huì)打印出來(lái)p2所指向的堆地址(實(shí)際此時(shí)p1指向的也是這個(gè)堆地址),兩次打印出來(lái)的字符串是不一樣的,因?yàn)閿?shù)值發(fā)生了改變。

下面附堆棧內(nèi)存圖來(lái)進(jìn)一步解釋。

第一次調(diào)用say方法時(shí)內(nèi)存狀態(tài):


第二次調(diào)用say方法時(shí)的內(nèi)存狀態(tài):



上面第二個(gè)圖畫錯(cuò)了,應(yīng)該是在第一個(gè)name和age改成“狗生”和“22”,第二個(gè)name和age還是空的。


將上面的代碼稍微改動(dòng)一下:
class People{
 public String name;
 public int age;
 public void say(){
  System.out.println("姓名:"+name+"  年齡:"+age);
 }
}
public class P1withP2 {
 public static void main(String[] args) throws InterruptedException {
  People p1 =new People();
  People p2 =new People();
  p1=p2;
  p1.name="大雨";
  p1.age=21;
  p2.name="狗生";
  p2.age=22;
  p1.say();
  p2.say();
 }
}

我們?cè)倏纯催\(yùn)行結(jié)果:


再看這個(gè)例子,里面先new了兩個(gè)對(duì)象,分別問(wèn)p1和p2,然后將p2的值附給了p1,這時(shí),p1的指向就發(fā)生了變化:p1就不再指向原來(lái)的地址了,此時(shí)p1就指向了p2所指向的地址了,也就是說(shuō):p1和p2指向了同一塊堆內(nèi)存。這時(shí)先給p1的屬性賦值(實(shí)際此時(shí)p2指向的也是這個(gè)堆地址);然后又給p2的屬性賦值(實(shí)際此時(shí)p1指向的也是這個(gè)堆地址),這個(gè)時(shí)候就出現(xiàn)了堆內(nèi)存里數(shù)據(jù)的覆蓋,這個(gè)時(shí)候調(diào)用了p1的say方法和p2的say方法,實(shí)際上兩次打印出來(lái)的字符串是一樣的,都是修改后的數(shù)據(jù),因?yàn)閮蓚€(gè)引用都是指向同一塊內(nèi)存地址。

下面附堆棧內(nèi)存圖來(lái)進(jìn)一步解釋。

第一次和第二次調(diào)用say方法時(shí)內(nèi)存狀態(tài):



上面第三個(gè)圖畫錯(cuò)了,應(yīng)該是在第一個(gè)name和age改成“狗生”和“22”,第二個(gè)name和age還是空的。


這就是對(duì)象引用的時(shí)候內(nèi)存管理的變化,希望這個(gè)例子能夠?qū)Υ蠹腋美斫鈨?nèi)存管理起到一定幫助作用。