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

到底是傳值還是傳引用?

系統 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條評論
主站蜘蛛池模板: 日韩欧美日本 | 日韩欧美在线视频 | 国产大学生一级毛片绿象 | 色女影院 | 久久人人网 | 日日噜噜夜夜躁躁狠狠 | 久久久久久免费视频 | 日韩做爰视频免费 | 久久精品动漫 | 97久久久久国产精品嫩草影院 | 国产最新网站 | 日本一级特大毛片 | 久久综合久久美利坚合众国 | 国产成+人+亚洲+欧美综合 | 亚洲欧美国产日产综合不卡 | 特级a欧美做爰片毛片 | 99j久久精品久久久久久 | 深夜福利视频网址 | 香蕉视频免费在线播放 | 国产成人精品曰本亚洲77美色 | 奇米影视777色 | 狠狠操.com| 日本欧美小视频 | 久久久久久麻豆 | 久久综合狠狠综合久久综合88 | 国产一区2区| 日本猛妇色xxxxx在线 | 无码免费一区二区三区免费播放 | 亚洲天堂久久新 | 久久 在线 | 免费视频久久久 | 国产伊人影院 | 亚洲在线国产 | 国产福利在线免费 | 国产一区二区三区影院 | 国产精品久久久久9999 | 丁香午夜婷婷 | 九九九热精品 | 男人的天堂免费在线观看 | 日本一级在线播放线观看免 | 欧美在线播放一区二区 |