Java中的值傳遞和"引用"傳遞

引言

學(xué)習(xí)過C語言的同學(xué)都很清楚在c中調(diào)用方法的參數(shù)有值傳遞和引用傳遞兩種方式。關(guān)于值傳遞和引用傳遞網(wǎng)上有許多的博客寫的很好,這里我就不解釋了。附上一篇:值傳遞和引用傳遞。但是使用過Java的同學(xué)可能知道,如果我們按照C語言的參數(shù)傳遞方式來理解Java中參數(shù)傳遞的話,有時候可能會和自己預(yù)料的答案有所出入。

Java中的參數(shù)傳遞方式

值傳遞

Java中的值傳遞指得是Java所提供的八種基本數(shù)據(jù)類型,不包括他們相應(yīng)的包裝類。

public class ReferTest {
    public static void main(String[] args){
        int data = 20;
        int res = basic(data);
        System.out.println("main:result data = " + res);
        System.out.println("main:data = " + data);
    }
    /**
     * 基本數(shù)據(jù)類型測試
     */
    public static int basic(int data){
        data = 25;
        System.out.println("basic:data = " + data);
        return data;
    }

上面的代碼是對基本數(shù)據(jù)類型傳遞的測試,在main方法中定義一個int型的數(shù),在basic方法中對改值進(jìn)行修改后返回,然后分別打印到控制臺。

basic:data = 25
main:result data = 25
main:data = 20

由打印結(jié)果我們可以看到有參數(shù)傳到basic中的data已經(jīng)在basic中被改變,并且也返回了被改變的數(shù)據(jù),但是data本身這個數(shù)并沒有改變,這說明,基本數(shù)據(jù)類型時通過值傳遞,main方法中的data和basic方法中的參數(shù)data并不是同一個。

引用傳遞

引用傳遞是指我們在傳遞參數(shù)的時候傳遞的是對象的引用而不是值,在Java中能被稱為引用的包括使用各種方法(new,反射)創(chuàng)建的對象,數(shù)組等。這里需要注意的是String是一個類而不是基本數(shù)據(jù)類型,他的實例是一個對象。

    public static void main(String[] args){
        int[] arrs ={10,6,4,8};
        ReferTest.sort(arrs);
        System.out.println("main:");
        for (int index:arrs) {
            System.out.print(index + " ");
        }
    }

    public static void sort(int[] arrs){
        Arrays.sort(arrs);
        System.out.println("sort:");
        for (int index:arrs) {
            System.out.print(index + " ");
        }
        System.out.println();
    }

這里使用數(shù)組來測試,首先創(chuàng)建了一個無序數(shù)組,將該數(shù)組作為參數(shù)傳遞到sort()方法中,調(diào)用api排序。

sort:
4 6 8 10
main:
4 6 8 10

可以看到結(jié)果中不僅sort()中的數(shù)組已經(jīng)被排序,main()中的數(shù)組也已經(jīng)排序,在這個測試中,我們并沒有指定返回值。這個結(jié)果和預(yù)期引用傳遞參數(shù)的方式一樣,那么這個測試能否說明Java和c++等方法一樣既有值傳遞又有引用傳遞呢?
繼續(xù)測試

public static void main(String[] args){
        int[] arrs ={10,6,4,8};
        ReferTest.sort(arrs);
        System.out.println("main:");
        for (int index:arrs) {
            System.out.print(index + " ");
        }
    }

    public static void sort(int[] arrs){
        int[] testArr = {9,4,2,7};
        arrs = testArr;
        Arrays.sort(arrs);
        System.out.println("sort:");
        for (int index:arrs) {
            System.out.print(index + " ");
        }
        System.out.println();
    }

我在sort()中又創(chuàng)建了一個數(shù)組,內(nèi)容和參數(shù)數(shù)組完全不同,然后將此數(shù)組賦值給參數(shù)數(shù)組,如果是引用傳遞的話,那么在main()中的數(shù)組也將變成testArr。

sort:
2 4 7 9
main:
10 6 4 8

然后結(jié)果和我們期望的并不一樣,這里sort()中數(shù)組已經(jīng)被賦值并且排序過了,但是main中的依然是之前的值,而且未經(jīng)過排序。那么很明顯Java中并不是使用的同c++一樣的引用排序。

解釋

在Java中,引用傳遞實際上不是傳遞的該引用本身,而是傳遞的該引用的一個副本,如果不對副本指向進(jìn)行修改,那么這個副本和引用值就是同一個地址,操作副本就相當(dāng)于操作引用,這里就和引用傳遞一致了。但是如對該副本修改了指向,那么修改的知識副本值,而不會對引用本身造成影響。

arrs = testArr;

當(dāng)程序走到這一步之前,大概是這樣的。圖只是為了方便理解,但是內(nèi)存中實際不是這樣的。

圖1

形參和實參指向同一片地址,這里就可以成為引用傳遞。而賦值過程完成后就成了這樣


圖2

形參的指向被改變了,指向的地址變化,這時候形參和實參已經(jīng)沒有了任何關(guān)系。對形參的任何修改都不會反映到實參中。
其實Java中對象到底是值傳遞或引用傳遞沒必要一定要在理論上確定一個答案,只要弄明白它的運(yùn)行原理,在使用中根據(jù)原理來合理的編寫代碼就可以了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 當(dāng)一個對象被當(dāng)作參數(shù)傳遞到一個方法后,此方法可改變這個對象的屬性,并可返回變化后的結(jié)果,那么這里到底是值傳遞還是引...
    峰峰小閱讀 413評論 0 1
  • 方法調(diào)用是編程語言中非常重要的一個特性,在方法調(diào)用時,通常需要傳遞一些參數(shù)來完成特定功能。 我們首先觀察一個簡單的...
    小人物灌籃閱讀 613評論 0 0
  • 今天復(fù)習(xí)Java基礎(chǔ),發(fā)現(xiàn)有一個概念好像有點模糊了,就是值傳遞,Think in Java中說Java只有值傳遞。...
    莫那一魯?shù)?/span>閱讀 692評論 0 4
  • 第5章 引用類型(返回首頁) 本章內(nèi)容 使用對象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,692評論 0 4
  • 當(dāng)然理性跟非理性就是用了對比的手法來詮釋了我們自己是一個什么樣的人,我大多表現(xiàn)都是非理性的,有時候會難以控制自...
    合肥李風(fēng)麗閱讀 323評論 4 0

友情鏈接更多精彩內(nèi)容