<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    夢想飛翔

    自強不息
    posts - 111, comments - 30, trackbacks - 0, articles - 0
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    ?

    提綱:
    1、版權聲明
    2、前言
    3、正文
    4、結論
    5、附注
    6、參考資料

    =======================================================

    1、版權聲明:
    ??本文作者:little,原始出處:用"堆棧區數據復制"理解Java賦值和參數傳遞機制的心得?([link]http://java.learndiary.com/disDiaryContentAction.do?goalID=2716[/link]),郵件:mdx-xx@tom.com。如有任何反饋意見請聯系作者,作者會在本文原始出處隨時更新此文。轉載及引用請保留此版權聲明,謝謝。

    2、前言:
    ??關于Java的賦值和參數傳遞是按值(by?value)進行的還是按引用(by?reference)進行的,這個問題曾經迷惑了很多人,包括我。而且,我想,這個問題還將繼續迷惑一些人,包括那些C++的高手。
    ??在這里,我不準備用“按值(by?value)”和“按引用(by?value)”這樣的術語來闡述這個問題。因為,從字面的理解來看,這樣的術語在不同的人頭腦里有不同的含義。我試圖從Java數據(包括原始類型(primitive?type)和對象(ojbect))在內存中的存儲這個角度,用一個自創的“術語”來闡述我對這個問題的理解。這個術語就是:“堆棧區數據復制(Stack?Data?Copy,簡稱SDC)”。詳細一點就是:在Java中,不管是賦值操作還是參數傳遞操作--針對原始類型(primitive?type),是對堆棧區的原始類型的值進行復制;針對對象,是對儲存在堆棧區的,對象的引用中所儲存的對象的值的地址進行復制。
    ??像上面摳字眼的句子讀起來比較費力,我在后面將用兩個例子并結合一些示意圖來闡述我對這個問題的理解。希望各位朋友幫助糾正錯誤。

    3、正文:
    1)、賦值操作:
    例子源碼:(Assign.java)

    1. public ?class?Assign{
    2. ??public?static?void?main(String[]?args){
    3. ????int?i?=?1;
    4. ????Object?o?=?new?Object();
    5. ????System.out.println("i?=?"?+?i?+?"?;?o?=?"?+?o?);?//?Step?1?(示意圖:3-1-1)
    6. ????int?j?=?i;???
    7. ????Object?p?=?o;
    8. ????System.out.println("i?=?"?+?i?+?"?;?j?=?"?+?j?+?"?;?o?=?"?+?o?+?"?;?p?=?"?+?p);?//Step?2?(示意圖:3-1-2)
    9. ????j++;
    10. ????p?=?new?Object();
    11. ????System.out.println("i?=?"?+?i?+?"?;?j?=?"?+?j?+?"?;?o?=?"?+?o?+?"?;?p?=?"?+?p);?//Step?3?(示意圖:3-1-3)
    12. ??}
    13. }


    對上面例子的說明:
    (1),Step?1中,整數i和對象o得到賦值。

    示意圖3-1-1

    ?
    chart3-1-1.bmp
    從示意圖3-1-1中可以看出:整數i存儲在堆棧區(Stack);對象o的引用存儲在了堆棧區,但是對象o的值卻存儲在了內存堆中(Heap),對象o的引用存儲了對象o的地址。
    Step?1在我的機器上的一次輸出結果:
    1. i?=?1?;?o?=?java.lang.Object@a90653

    至于對象o的值輸出來怎么會是那個樣子,我只能告訴您:在java程序的一次運行過程中,每個Object對象輸出這樣的值是唯一的,因此可以借此來判斷對象的引用指向的對象是否發生了改變。詳情請參考Java?API?文檔(下同,這里給出的是:J2SE?1.5.0?API?中文版):
    [link]http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/java/io/PrintStream.html#println(java.lang.Object)[/link]
    [link]http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/java/lang/Object.html#toString()[/link]
    (2),Step?2中,把整數i賦值給了整數j,把對象o賦值給了對象p。

    示意圖3-1-2

    chart3-1-2.bmp

    從示意圖3-1-2中可以看出:整數i的值復制給了整數j,整數j同樣存儲在堆棧區;存儲在堆棧區的對象o的引用中存儲的對象o的地址C復制給了對象p的引用,對象p的引用同樣在堆棧區中。因為對象p的引用得到了對象o的引用復制過來的對象o的值的存儲地址C,所以對象p的引用和對象o的引用都指向了在堆(heap)中的同一個對象,并且,這個對象的地址是地址C。
    Step?2在我的機器上的一次輸出結果:
    1. i?=?1?;?j?=?1?;?o?=?java.lang.Object@a90653?;?p?=?java.lang.Object@a90653

    (3),Step?3中,整數j的值加1,賦給了對象p新的對象值。

    示意圖3-1-3

    chart3-1-3.bmp

    從示意圖3-1-3中可以看出:整數i的值不變,整數j的值加1變為2,整數在堆棧區中;新生成的對象的值存儲在了堆(Heap)中,地址為F。新生成對象的地址F存儲在了堆棧區p的引用中,替換了原來存儲在其中的地址C。于是,p的引用就指向了新生成的對象,這個新生成的對象的地址是地址F。而整數i和對象o的?(包括對象o的引用)沒有改變也不曾有任何改變(除了初次賦值)。
    Step?3在我的機器上的一次輸出結果:
    1. i?=?1?;?j?=?2?;?o?=?java.lang.Object@a90653?;?p?=?java.lang.Object@de6ced


    至此,通過上面的例子及其示意圖和說明,我得到一個結論:
    在Java賦值操作中,針對原始類型(primitive?type),是對堆棧區的原始類型的值進行復制;針對對象,是對儲存在堆棧區的,對象的引用中所儲存的對象的值的地址進行復制。這就是術語:“堆棧區數據復制(Stack?Data?Copy,簡稱SDC)”在Java賦值操作中的闡述。

    2)、方法中的參數傳遞操作:
    例子源碼:(PassParameter.java)
    1. public?class?PassParameter{
    2. ??static?void?showMe(int?pi,?Object?po){
    3. ????System.out.println("pi?=?"?+?pi?+?"?;?po?=?"?+?po);?//?Step?2?(示意圖:3-2-2)
    4. ????pi++;
    5. ????po?=?new?Object();
    6. ????System.out.println("pi?=?"?+?pi?+?"?;?po?=?"?+?po);?//?Step?3?(示意圖:3-2-3)
    7. ??}
    8. ??public?static?void?main(String[]?args){
    9. ????int?i?=?1;
    10. ????Object?o?=?new?Object();
    11. ????System.out.println("i?=?"?+?i?+?"?;?o?=?"?+?o);?//?Step?1?(示意圖:3-1-1)
    12. ????showMe(i,?o);
    13. ????System.out.println("i?=?"?+?i?+?"?;?o?=?"?+?o);?//?Step?4?(示意圖:3-2-3)
    14. ??}
    15. }


    對上面例子的說明:
    (1),Step?1中,與上面Assign.java中的Step?1相同,略,下面重復其示意圖3-1-1。

    示意圖3-1-1

    chart3-1-1.bmp
    ?

    Step?1在我的機器上的一次輸出結果:
    1. i?=?1?;?o?=?java.lang.Object@a90653

    (2),Step?2中,與上面Assign.java中的Step?2類似,只是Assign.java中的整數j和對象p變成了這里的方法showMe()中的參數:整數pi和對象po。并且,由于這里是參數傳遞,把Assign.java示意圖3-1-2中的“=”替換成PassParameter.java示意圖3-2-2中的“<--”,以此表示是參數傳遞。據我的理解,它們是一回事。

    示意圖3-2-2

    chart3-2-2.bmp

    Step?2在我的機器上的一次輸出結果:
    1. pi?=?1?;?po?=?java.lang.Object@a90653

    (3),Step?3和Step?4合并起來,見示意圖3-2-3同樣,與上面Assign.java中的Step?3類似。

    示意圖3-2-3

    ?chart3-2-3.bmp

    Step?3和Step?4在我的機器上的一次輸出結果:
    1. pi?=?2?;?po?=?java.lang.Object@de6ced
    2. i?=?1?;?o?=?java.lang.Object@a90653


    至此,通過上面的例子及其示意圖和說明,我得到一個結論:
    在Java方法參數傳遞操作中,針對原始類型(primitive?type),是對堆棧區的原始類型的值進行復制;針對對象,是對儲存在堆棧區的,對象的引用中所儲存的對象的地址的值進行復制。這就是術語:“堆棧區數據復制(Stack?Data?Copy,簡稱SDC)”在Java方法參數傳遞操作中的闡述。

    4,結論
    綜上所述:在Java中,不管是賦值操作還是方法的參數傳遞操作--針對原始類型(primitive?type),是對堆棧區的原始類型的值進行復制;針對對象,是對儲存在堆棧區的,對象的引用中所儲存的對象的值的地址進行復制。
    所以,據我的理解,術語:“堆棧區數據復制(Stack?Data?Copy,簡稱SDC)”能夠有助于理解在Java中進行賦值和傳遞參數的機制,能夠有助于在一定程度上消除“傳值”、“傳引用”等語義上的多變性的負面影響,可以提出來供大家交流。

    5,附注:
    由于本人水平有限,上面的一切全是基于實踐進行的帶有一些推測成分在內的個人心得總結。我也以上面的自創術語去成功解釋過一些文章中的有關問題(如下面參考資料中的例程)。謹希望在能為部分Java初學者提供一個理解Java賦值和參數傳遞的手段的同時,更能得到各位朋友的斧正,以便能夠對這個問題形成更加正確和準確的認識。在我提高認識的同時,我會在本文原始出處:用"堆棧區數據復制"理解Java賦值和參數傳遞機制的心得?([link]http://java.learndiary.com/disDiaryContentAction.do?goalID=2716[/link])中隨時更新此文。再次貼出我的郵件:mdx-xx@tom.com。謝謝。

    6,參考資料:

    1),Java參數傳遞方式?([link]http://www.jiehoo.com/java-pass-parameter.htm[/link])
    2),破除java神話之二:參數是傳址的?([link]http://www.javaresearch.org/article/showarticle.jsp?column=544&thread=443[/link])
    3),Java?應用程序中的按值傳遞語義?([link]http://www.javaresearch.org/article/showarticle.jsp?column=1&thread=706[/link])
    4),我對《Java?應用程序中的按值傳遞語義》的理解?([link]http://www.javaresearch.org/article/showarticle.jsp?column=1&thread=3156[/link])
    5),Thinking?in?Java,?3rd?Edition?in?Java?([download]http://www.mindviewinc.com/downloads/TIJ-3rd-edition4.0.zip[/download])

    ??????????????????????????????????????????????????????????????全文完
    ??????????????????????????????????????????????????????????????2006年11月22日午????
    主站蜘蛛池模板: 国产亚洲一区二区三区在线| 免费可以看黄的视频s色| 精品国产污污免费网站入口| 人人鲁免费播放视频人人香蕉| 看亚洲a级一级毛片| 处破女第一次亚洲18分钟| 国产尤物在线视精品在亚洲| 日本系列1页亚洲系列| 国产成人综合亚洲绿色| 猫咪免费观看人成网站在线| 污视频网站免费在线观看| 一个人免费观看日本www视频| 中文字幕成人免费高清在线视频| A毛片毛片看免费| 久久精品视频免费看| 97av免费视频| 成人免费a级毛片| 在线观看亚洲免费视频| 无码不卡亚洲成?人片| 国产日产亚洲系列| 亚洲av无码不卡一区二区三区| 97se亚洲综合在线| 亚洲最大成人网色香蕉| 亚洲国产欧美国产综合一区| 羞羞网站免费观看| 中文在线免费看视频| 88av免费观看入口在线| 手机在线免费视频| 亚洲精品高清在线| 香蕉视频在线观看亚洲| 亚洲香蕉久久一区二区三区四区| 亚洲欧美日韩国产成人| xxxx日本在线播放免费不卡| 一级毛片成人免费看免费不卡| 青娱乐免费视频在线观看| 免费人成网站在线高清| 国产成人亚洲综合无码精品 | 午夜色a大片在线观看免费| 国产免费久久精品| 亚洲AV无码专区国产乱码4SE| 亚洲人成片在线观看|