亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

到底是傳值還是傳引用?

系統 1760 0

發現關于java中值傳遞還是引用傳遞,一些誤解挺多的,我的觀點(其實也不是我的觀點,咱都是二手販子)就是java中只有值傳遞;來吧,咱從頭來捋一下,本山大叔在賣拐里不是說了嘛,亂了咱就捋,從頭捋一下。

1. 啥叫值傳遞,啥叫引用傳遞。

在編譯原理中,我們會看到參數的傳遞有四種,定義如下:

Pass by value : This is the? mechanism supported by C . Value of parameters are copied into called routine.

Pass by reference : No copying is done, but a reference (usually implemented as a pointer) is given to the value. In addition to allowing the called routine to change the

values, it is also efficient means for passing large variables (such as structs ).

Pass by value-result : This interesting variant supported by languages such as Ada copies the value of the parameter into the routine, and then copies the (potentially changed)

value back out. This has an effect similar to pass-by-reference, but not exactly.

Pass by name : This rather unusual mechanism acts somewhat like C preprocessor macros and was introduced in Algol . Rather than evaluating the parameter value, the name or expression is actually substituted into the calling sequence and each? access to the parameter in the calling body re- evaulates it.

?

由定義可知:并不是我們傳遞某個參數時,若這個參數是某對象的引用,所以這就是引用傳遞,引用傳遞在程序設計領域有其自己的意義。

2. 參數傳遞是通過值傳遞,不是通過引用傳遞。

其實很多書籍都講到這一點,如 practical java 第一條講的就是它。 我們有時候會聽到說某方法傳遞了一個引用,其實應該說準確點,傳遞的是一個引用(型變量)-pass object reference by value,其傳遞的內容依然是這個引用型變量的值,即:還是值傳遞。對象都是通過其對象變量來標識的,而這個對象變量的值并不是對象本身,僅僅是存儲在另外一處的該對象的引用。網上很多文章會講到:這是不對的。

混淆值傳遞和引用傳遞通常會有個負面作用:一般認為引用傳遞的結論還會加上一條-對引用的改變會影響原有變量的值--當然,我們認為這是錯誤的。

?? ? ? ? 看下面的代碼:

    import java.util.ArrayList;
import java.util.List;

public class ByValue {
    public static void main(String args[]) {

        // 1.pass primitive type parameter.
        int i = 0;
        System.out.println("initially the i is " + i);
        byPrimitive(i);
        System.out.println("now the i is " + i);

        // 2. pass reference type parameter and change the parameter's initial value.
        List<String> strList = new ArrayList<String>();
        strList.add("hello world");
        System.out.println("initially the strList is" + strList.toString());
        refType(strList);
        System.out.println("now the strList is" + strList.toString());

        // 3.pass reference type parameter and remain the parameter's initial value .
        List<String> strList2 = new ArrayList<String>();
        strList2.add("hello world ");
        System.out.println("initially the strList2 is" + strList2.toString());
        refType2(strList2);
        System.out.println("now the strList2 is" + strList2.toString());


        List<String> strList3 = new ArrayList<String>();
        strList3.add("hello world 3");
        List<String> strList3Ref = new ArrayList<String>();

        // 4.deep copy
        strList3Ref.addAll(strList3);
        // 5.shallow copy
        strList3.add("hi jude 3");

        System.out.println("now strList3: " + strList3);
        System.out.println("now strList3Ref: " + strList3Ref);
    }

    //1. 修改基本 型變量拷貝的值
    //1.1 在棧內存 的新地址中復制了i的拷貝i',i'的值也是0;
    //1.2 修改了 i'的值為3;
    //1.3 i的值沒有 變化
    private static void byPrimitive(int i) {
        i = i + 3;
        System.out.println("the i' is :" + i);
    }

    //2.修改引用 型變量的拷貝的所引用的對象。
    // 2.1 在棧內存 中復制了strList的拷貝 值,新建了引用strList’,strList’的值等同 于strList的值, 即:指向同樣的一片堆內存區域;
    // 2.2,對strList'引用的對 象做了修改;2.3因為strList所引用的 對象就是strList'所引用的 對象,所以strList的引用對 象發生了變化。
    private static void refType(List<String> strList) {
        strList.add("hi jude");
        System.out.println("the strList' is :" + strList);
    }

    //3 修改引用 型變量的拷貝的引用。
    //3.1 在棧內存 中復制了strList2的拷貝 值,新建了引用strList2’,strList2'的值等同 于strList2的值, 即:指向同樣的一片內存區域;
    //3.2 對strList2'做修改, 即,使其成為局部變量targetList所引用對 象的引用。
    //3.3 修改strList2'所引用對 象的值,即strList2'所引用對 象發生了改變,strList2卻沒有變 化。
    private static void refType2(List<String> strList) {
        List<String> targetList = new ArrayList<String>();
        strList = targetList;
        strList.add("hi jude");
        System.out.println("the strList' is :" + strList);
    }

}
  
?

以上代碼中的注釋已經基本清晰,第三種種" 修改引用型變量的拷貝的引用"我個人感覺用途很少, 在實際中若是在傳遞值過程中不想改變原有引用的對象,一般都會
先將該變量所引用的對象內容先拷貝一份, 然后再對其操作,這樣就不會修改原值。對此,我們會注意到另外一個話題,就
是淺拷貝和深拷貝,在第三點我們再細述。
上面三種情況的內存分配圖如下:

      1. 修改基本 型變量拷貝的值
    


到底是傳值還是傳引用?

?

    2.修改引用 型變量的拷貝的所引用的對象。
  


到底是傳值還是傳引用?

?

        3. 修改引用 型變量的拷貝的引用。
  

到底是傳值還是傳引用?

?

?

?


?

?

3.? 淺拷貝 ? 深拷貝 .

?? ?引用到三方方法時得考慮,such as? Collection.add() 和 collection.addAll(),見代碼4和5部分。

?

4. 為啥會有誤解?

?? ?4.1 一種:因為java中的對象都是靠對象變量即引用來標識的,所以參數傳遞中試引用時,當然就是引用傳遞了。

?? ? ? ? ?解釋:如果傳遞了Object reference那么就是by reference,那么對應的基本類型(primitive type)的參數傳遞應該就是by primitive ,在這會,reference type 和primitive type是一對對立統一的范疇,在命名上不能顧此失彼吧。歸根到底還是對by reference and by value的定義不清楚,參見我們捋的第一條。

?? ?4.2 另外一種:參數傳遞中,會改變原來的變量的值,所以是引用傳遞。

?? ? ? ? ?解釋:在 所謂的call by reference中,有時候原變量的值,其所引用的對象存在不改變的情況。參見例子.所以不能成為理由。

?? ?4.3 與C++中的by reference混淆。

?

5. 最后,你實在不相信我說的,也該相信Java他爹說的話吧?

Some people will say incorrectly that objects are passed "by reference. " In programming language design, the term pass by reference properly means that when an argument is passed to a function, the invoked function gets a reference to the original value, not a copy of its value. If the function modifies its parameter, the value in the calling code will be changed because the argument and parameter use the same slot in memory. If the Java programming language actually had pass-by-reference parameters, there would be a way to declare halve it so that the above code would modify the value of one, or so that common Name could change the variable sirius to null. This is not possible. The Java programming language does not pass objects by reference; it passes object references by value. Because two copies of the same reference refer to the same actual object, changes made through one reference variable are visible through the other. There is exactly one parameter passing mode pass by value and that helps keep things simple.

?

?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?-----Gosling. The Java Programming Language 第2章 第6節

?

?

?

?

到底是傳值還是傳引用?


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚洲欧洲成人 | 免费观看一级毛片 | 99热这里只有成人精品国产 | 亚洲男人的天堂久久香蕉 | 鲁一鲁射一射 | 香蕉爱爱网 | 天天躁狠狠躁夜夜躁 | 欧美成人h | 亚洲一区二区精品 | 久久成人免费播放网站 | 国产美女久久久亚洲 | 欧美在线一区视频 | 国产精品成人久久久久 | 国产视频一区二区在线播放 | 国产一区国产二区国产三区 | 亚洲视频1区 | 成人欧美日韩高清不卡 | 日韩免费小视频 | 99在线热视频只有精品免费 | 四虎精品影院在线观看视频 | 99久久99久久免费精品蜜桃 | 久久综合九色综合97_ 久久久 | 色老头久久网 | 色播性播爱播放影院 | 日韩精品午夜视频一区二区三区 | 亚洲一区二区三区精品视频 | 中国特级黄一级真人毛片 | 欧美亚洲桃花综合 | 九九热播视频 | 欧洲a视频| 又刺激又黄的一级毛片 | 色激情综合网 | 神马毛片 | 在线韩日 | 免费一级a毛片夜夜看 | 青青青草视频在线 | 欧美日韩国产高清视频 | 日韩欧美一区二区久久黑人 | 99这里有精品视频 | 草草视频免费观看 | 欧美日韩高清 |