把困難踩在腳下

          迎難而上

           

          引用類(lèi)型數(shù)據(jù)在內(nèi)存中的存儲(chǔ)過(guò)程

          基本類(lèi)型數(shù)據(jù)在內(nèi)存中的存儲(chǔ)非常簡(jiǎn)單,引用類(lèi)型是把對(duì)象的地址放到棧內(nèi)存中,數(shù)據(jù)放在堆內(nèi)存中。在這通過(guò)幾個(gè)小程序簡(jiǎn)單描述一下引用類(lèi)型數(shù)據(jù)在內(nèi)存中的存儲(chǔ)過(guò)程:
          class Person{
               String name;
               int age;
               void say(){
                    System.out.println("姓名:"+name+",年齡:"+age);
               }
          }
          public class Demo01{
                 public static void main(String args[]){
                 Person p1=new Person();
                 Person p2=new Person();
                 p1.name="張三";
                 p1.age=20;
                 p2=p1;
                 p1.say();
                 p2.say();
                 p2.name="李四";
                 p2.age=40;
                 p1.say();
                 p2.say();
                  }
          }
          上面的程序先新建了一個(gè)Person類(lèi),里面有兩個(gè)成員變量還有一個(gè)成員方法。然后創(chuàng)建了一個(gè)Demo01類(lèi)。執(zhí)行如下代碼:
          Person p1=new Person;
          Person p2=new Person();
          就會(huì)為兩個(gè)Person實(shí)例對(duì)象分配內(nèi)存空間,將兩個(gè)對(duì)象初始化,內(nèi)存分配如圖1所示:

          執(zhí)行
           p1.name="張三";
           p1.age=20;為實(shí)例對(duì)象p1賦值,內(nèi)存分布如圖2所示:

          執(zhí)行
            p2=p1;是將實(shí)例對(duì)象p2指向?qū)嵗龑?duì)象p1的內(nèi)存空間,原來(lái)為實(shí)例對(duì)象p1分配的內(nèi)存空間就會(huì)失去指向,這樣當(dāng)系統(tǒng)執(zhí)行垃圾(GC)技術(shù)時(shí)就會(huì)將這一部分內(nèi)存釋放。內(nèi)存分步如圖3所示:

          執(zhí)行
          p1.say();
          p2.say();
          就會(huì)輸出:
          姓名:張三,年齡:20
          姓名:張三,年齡:20
          執(zhí)行
          p2.name="李四";
          p2.age=40;
          就會(huì)將原先的值覆蓋,內(nèi)存分配如圖4所示:

          執(zhí)行
          p1.say();
          p2.say();
          就會(huì)輸出
          姓名:李四,年齡:40
          姓名:李四,年齡:40
          這就是引用類(lèi)型數(shù)據(jù)的存儲(chǔ)過(guò)程。java程序采用這種存儲(chǔ)方式主要有兩個(gè)原因:
          1.棧內(nèi)存存取速度非常快,僅次于寄存器。2.與垃圾回收機(jī)制(GC)相連,有利于機(jī)制刪除沒(méi)有指向的堆內(nèi)存數(shù)據(jù),釋放內(nèi)存空間。
          上面的程序執(zhí)行
          p2=p1;
          這條語(yǔ)句后,將p2指向了p1所指向的數(shù)據(jù)并不能完成復(fù)制功能,我們可以稍作修改就可以完成復(fù)制功能,程序如下:
          class Person{
               String name;
               int age;
               void say(){
                    System.out.println("姓名:"+name+",年齡:"+age);
               }
          }
          public class Demo02{
                 public static void main(String args[]){
                 Person p1=new Person();
                 Person p2=new Person();
                 p1.name="張三";
                 p1.age=20;
                 p2.name=p1.name;
                 p2.age=p1.age;
                 p1.say();
                 p2.say();
                 p2.name="李四";
                 p2.age=40;
                 p1.say();
                 p2.say();
                  }
          }
          這個(gè)程序的輸出結(jié)果是:
          姓名:張三,年齡:20
          姓名:張三,年齡:20
          姓名:張三,年齡:20
          姓名:李四,年齡:40
          我們來(lái)分析它的內(nèi)存存儲(chǔ)過(guò)程,執(zhí)行代碼
           Person p1=new Person();
          Person p2=new Person();
          p1.name="張三";
          p1.age=20;
          它的存儲(chǔ)過(guò)程如圖1和圖2相同,執(zhí)行代碼
          p2.name=p1.name;
          p2.age=p1.age;
          它并沒(méi)有將p2指向p1所指向的數(shù)據(jù),而是將p1所指向的數(shù)據(jù)復(fù)制給p1所指向的數(shù)據(jù)。它的內(nèi)存分配過(guò)程如圖5所示:

          執(zhí)行代碼
          p1.say();
          p2.say();
          就會(huì)輸出
          姓名:張三,年齡:20
          姓名:張三,年齡:20
          執(zhí)行代碼
          p2.name="李四";
          p2.age=40;
          修改了p2所指向的數(shù)據(jù)的值,但沒(méi)有修改p1所指向的數(shù)據(jù)的值。內(nèi)存分配過(guò)程如圖6所示:

          執(zhí)行代碼
          p1.say();
          p2.say();
          就會(huì)輸出
          姓名:張三,年齡:20
          姓名:李四,年齡:40
          下面我們看下一個(gè)程序
          class Person{
             String name;
             int age;
             public void  setName(String name){
                   this.name=name;
             }
             public void setAge(int age){
                   this.age=age;
              }
              public String getName(){
                   return name;
              }
               public int age(){
                    return age;
              }
              public void say(){
                    System.out.println("姓名:"+name+",年齡:"+age);
             }
          }
          public class Demo03{
                public static void main(String args[]){
                Person[]  per=new Person[2];
                per[0]=new Person();
                per[1]=new Person();
                per[0].setName("張三");
                per[0].setAge(20);
                per[1].setName("李四");
                per[1].setAge(40);
                for(int i=0;i<per.length;i++){
                 per[i].say();  
                }
                }
          }
          上面的程序輸出結(jié)果為
          姓名:張三,年齡:20
          姓名:李四,年齡:40
          此程序首先建立一個(gè)Person類(lèi),里面有成員變量和成員方法,然后定義一個(gè)Demo03類(lèi),執(zhí)行代碼
          Person[]  per=new Person[2];
          per[0]=new Person();
          per[1]=new Person();
          建立一個(gè)Person對(duì)象的數(shù)組并初始化,這里的初始化只是將數(shù)組元素指向null,而并沒(méi)有在堆內(nèi)存中分配空間,內(nèi)存存儲(chǔ)如圖7所示:

          執(zhí)行代碼
          per[0]=new Person();
           per[1]=new Person();
          這才是為數(shù)組元素開(kāi)辟了堆內(nèi)存空間并初始化,如圖8所示:

          執(zhí)行代碼
          per[0].setName("張三");
          per[0].setAge(20);
          per[1].setName("李四");
          per[1].setAge(40);
          將張數(shù)據(jù)存儲(chǔ)到各個(gè)數(shù)組元素所指向的堆內(nèi)存中,如圖9所示:

          執(zhí)行代碼
           for(int i=0;i<per.length;i++){
                 per[i].say();  
                }
          是將數(shù)組中的值輸出出來(lái),就會(huì)輸出以上輸出結(jié)果。
          java引用類(lèi)型的存儲(chǔ)過(guò)程就是這樣。這只是在下的一個(gè)小見(jiàn)解,可能有不到位或不

          正確的地方,歡迎各位朋友提出見(jiàn)解,共同分享知識(shí)。

          posted on 2010-10-13 08:26 馮魁 閱讀(823) 評(píng)論(2)  編輯  收藏

          評(píng)論

          # re: 引用類(lèi)型數(shù)據(jù)在內(nèi)存中的存儲(chǔ)過(guò)程 2010-10-13 09:03

          很不錯(cuò),有創(chuàng)意!  回復(fù)  更多評(píng)論   

          # re: 引用類(lèi)型數(shù)據(jù)在內(nèi)存中的存儲(chǔ)過(guò)程 2012-11-16 09:27 ..

          ...............  回復(fù)  更多評(píng)論   


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           

          導(dǎo)航

          統(tǒng)計(jì)

          公告

          快樂(lè)每一天!

          Everything is an object!

          常用鏈接

          留言簿(2)

          隨筆檔案

          學(xué)習(xí)網(wǎng)站

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 玉林市| 大石桥市| 灵武市| 霍林郭勒市| 龙江县| 沈丘县| 岗巴县| 淮南市| 尤溪县| 江阴市| 长沙县| 淮北市| 四子王旗| 乌兰浩特市| 莲花县| 东乡族自治县| 武强县| 双柏县| 孟津县| 泌阳县| 乌恰县| 柘荣县| 华蓥市| 丽水市| 武定县| 兴城市| 泸溪县| 哈巴河县| 长葛市| 双峰县| 宁强县| 嘉义县| 霍林郭勒市| 宁阳县| 施秉县| 荃湾区| 西充县| 牟定县| 博爱县| 东台市| 临漳县|