• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Shuffy

            不斷的學(xué)習(xí),不斷的思考,才能不斷的進步.Let's do better together!
            posts - 102, comments - 43, trackbacks - 0, articles - 19

            java經(jīng)典問題:傳值還是傳引用

            Posted on 2008-10-13 14:54 Shuffy 閱讀(556) 評論(0)  編輯 收藏 引用 所屬分類: Java

            本文摘自:http://www.chinaunix.net/jh/26/719880.html

            “java函數(shù)是傳值的,java函數(shù)傳遞的參數(shù)是對象的引用值”
            下面通過一個例子來說明:

            public class TestRef {
                 
                  public static void main(String[] args)
                  {
                        ValueObject vo1 = new ValueObject("A", 1);
                        System.out.println("after vo1: " + vo1.getName()); //=A
                       
                        changeValue1(vo1);
                        System.out.println("after changeValue1: " + vo1.getName());
                            //=A1, changed
                       
                        changeValue2(vo1);
                        System.out.println("after changeValue2: " + vo1.getName());
                            //=A1, changeValue2內(nèi)部的賦值不會影響這里。
                  }

                  /**
                   * 使用vo1自身的函數(shù)對其內(nèi)部數(shù)據(jù)進行改變是有效的,函數(shù)外可反映出來
                   * 這種object稱為可變的(mutable)
                   * @param vo1
                   */
                  private static void changeValue1(ValueObject vo1) {
                        vo1.setName("A1");
                  }

                  /**
                   * 在函數(shù)內(nèi)給vo1重新賦值不會改變函數(shù)外的原始值
                   * @param vo1
                   */
                  private static void changeValue2(ValueObject vo1) {
                        vo1 = new ValueObject("B", 2);
                        System.out.println("inside changeValue2: "+ vo1.getName());
                            //=B,賦值操作引起的結(jié)果變化僅在changeValue2內(nèi)部有效
                  }
            }

            class ValueObject {
                 
                  public ValueObject() {}
                 
                  public ValueObject(String name, int id)
                  {
                        this.name = name;
                        this.id = id;
                  }
                 
                  private String name;
                  private int id;
                  public int getId() {
                        return id;
                  }
                  public void setId(int id) {
                        this.id = id;
                  }
                  public String getName() {
                        return name;
                  }
                  public void setName(String name) {
                        this.name = name;
                  }
            }

             

            解釋,vo1作為一個object,當它被用作函數(shù)參數(shù)的時候傳遞給函數(shù)的是一個引用值,這個名稱有點怪,又有引用又有值,到底是引用還是值呢,就看你怎么理解了。如果你是去考試,官方的答案是值。可是看起來又象引用啊,希望從這個例子,你能理解java參數(shù)傳遞和和C/C++程序中的引用傳遞的不同的地方。另外,這也是java作為OO語言的特性之一:封裝的體現(xiàn)。

            先講一下對象賦值的關(guān)系,舉例來說,下列代碼:

            ValueObject v2, v3;
            v2 = new ValueObject("C", 3); 粗體的部分創(chuàng)建了一個數(shù)據(jù)結(jié)構(gòu),假設(shè)存放在內(nèi)存地址A000,賦值給句柄 v2
            v3 = new ValueObject("D", 4); 粗體的部分創(chuàng)建了一個數(shù)據(jù)結(jié)構(gòu),假設(shè)存放在內(nèi)存地址B000,賦值給句柄 v3
            v2 = v3; 這句話的作用是把操作B000的地址的句柄的值付給了v2的句柄,使得v2和v3一樣操作B000的地址,這意味著:
            1.原來v2指向的地址A000變成無主的內(nèi)存地址,將自動被jvm回收。
            2.既然v2和v3指向同一片地址,對v3的修改v2也能得到,反之亦然。

            整理得下列代碼,請感興趣的朋友運行驗證
            ValueObject v2 = new ValueObject("C", 3);
            ValueObject v3 = new ValueObject("D", 4);
            v2 = v3;
            System.out.println("after v2=v3");
            System.out.println("v2= "+ v2.getName());//=D
            System.out.println("v3= "+ v3.getName());//=D
            v3.setName("C1");
            System.out.println("after v3 setnameTo C1");
            System.out.println("vo2= "+ v2.getName());//=C1
            System.out.println("vo3= "+ v3.getName());//=C1

            因此,可以得出結(jié)論,java中對象的每個實例(instance, 比如vo1, v2, v3 都是ValueObject的實例)的內(nèi)存地址是唯一的,它一旦被創(chuàng)建,能夠?qū)@個地址進行操作的就是每個實例自己,如果ValueObject類中沒有public void setName之類的方法對這個類的實例中的數(shù)據(jù)進行修改的話,程序是沒有任何別的方法可以修改ValueObject類的實例中的數(shù)據(jù),這個就是java的封裝特性。對于不提供修改內(nèi)部數(shù)據(jù)的方法的類,我們稱為不可變(immutable)的類。在函數(shù)中對傳入的參數(shù)變量進行賦值操作,只能在函數(shù)范圍內(nèi)改變局部變量指向的引用地址,但是不會改變原始地址的內(nèi)容。因此,在changeValue2(...)函數(shù)內(nèi)部的vo1和函數(shù)外的vo1雖然名字相同,但是實際上是不同的實例變量,只不過指向了和函數(shù)外的vo1同樣的地址,所以當我們用vo1=... 對其進行賦值的時候,只不過是把函數(shù)內(nèi)的臨時變量指向了新的地址,并沒有改變原始vo1內(nèi)存地址中的內(nèi)容。這就是在運行changeValue2(...)之后,vo1的值在main范圍內(nèi)仍然沒有被修改的原因。而changeValue1里面是調(diào)用的ValueObject本身的function來更改其內(nèi)容,因此是原始內(nèi)存地址中的數(shù)據(jù)被更改了,所以是全局有效的。

            久久精品国产99国产精品导航| 久久AV高潮AV无码AV| 亚洲国产精久久久久久久| 99久久亚洲综合精品成人| 久久综合色之久久综合| 亚洲熟妇无码另类久久久| 久久久久夜夜夜精品国产| 一级女性全黄久久生活片免费| 欧洲人妻丰满av无码久久不卡| 久久久久免费视频| 久久夜色精品国产网站| 久久精品一区二区三区中文字幕| 久久人人爽人人爽人人片AV不 | 一本综合久久国产二区| 久久无码人妻一区二区三区午夜| 国产伊人久久| 欧美精品一区二区精品久久| 久久国产免费直播| 国产精品免费看久久久香蕉| 国产偷久久久精品专区| 性欧美大战久久久久久久| 国产精品99久久久久久人| 亚洲AV无一区二区三区久久| 久久中文精品无码中文字幕| 国产精品日韩深夜福利久久| 久久精品国产精品青草| 久久天天躁狠狠躁夜夜网站| 亚洲人成伊人成综合网久久久| 久久亚洲av无码精品浪潮| 久久精品国产亚洲一区二区三区| 久久se精品一区二区| 久久免费高清视频| 99久久精品国内| 久久本道伊人久久| 亚洲国产精品久久| 精品久久久久中文字幕一区| 久久www免费人成精品香蕉| 精品久久久久久国产三级 | 久久婷婷人人澡人人爽人人爱| 久久天天躁夜夜躁狠狠躁2022| 久久久久久久久波多野高潮|