搜尋

首頁  >  問答  >  主體

关于Java引用传递的一个困惑?

    public static void swapEqual(int[] a,int[] b){
        int[] temp=new int[b.length];
        temp=b;
        b=a;
        a=temp;
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] c={1,2};
        int[] d={3,4};
        swapEqual(c,d);
        System.out.println(c[1]);
    }

为什么打印出来的C[1]还是原来的2啊,为什么没有交换。数组的=不就是复制引用吗?通过函数可以把a,b的引用交换,这样不就是把内容交换了吗?
干嘛非要这样写?
public static void swap(int[] a,int[] b){
    int[] temp=new int[b.length];
    for(int i=0;i<b.length;i++){
        temp[i]=b[i];
    }
    for(int i=0;i<b.length;i++){
        b[i]=a[i];
    }
    for(int i=0;i<b.length;i++){
        a[i]=temp[i];
    }
}

这样子我试了一下,就可以达到交换的目的了
好困惑啊,求解!!

ringa_leeringa_lee2802 天前549

全部回覆(6)我來回復

  • PHPz

    PHPz2017-04-18 10:49:30

    swapEqual(int[] a,int[] b)中:
    一開始:
    a --> {1,2}(地址1)
    b --> {3,4}(地址2)
    經過你的程式碼處理(a,b指向的位址交換了):
    b --> {1,2}(位址1)
    a --> {3,4}(位址2)
    但是不會對c,d造成影響,c,d依舊是:
    c --> {1,2}(位址1)
    d --> {3,4}(位址2)

    //=================================

    swap(int[] a,int[] b)中:
    一開始:
    a --> {1,2}(地址1)
    b --> {3,4}(地址2)
    經過你的代碼處理(地址1,2中的值交換了):
    a --> {3,4}(地址1)
    b --> {1,2}(地址2)
    雖然不會對c, d指向的位址造成影響,但原本位址下的值已經改變了:
    c --> {3,4}(位址1)
    d --> {1,2}(位址2)

    //=======================================

    我的理解是這樣,寫完發現與@lianera的表述是同一個意思,就當是補充說明了。

    //=======================================

    你可以試著用return把swapEqual(int[] a,int[] b)交換後的a,b的值賦給c,d,看看結果。

    回覆
    0
  • PHP中文网

    PHP中文网2017-04-18 10:49:30

    swapEqual函數裡面,只是改變了形參a、b的引用,並沒有改變實參c、d的引用。
    而swap裡面,改變的c、d對應的區域的值了。
    補充一下,Java裡面數組也是對象,所以a、b、c、d都是引用。

    回覆
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-18 10:49:30

    Java 裡的引用和 C++ 裡的引用概念有點不一樣,Java 裡的引用相當於 C++ 中的指針,所以你直接對形參賦值是改變不了實參的。

    回覆
    0
  • 天蓬老师

    天蓬老师2017-04-18 10:49:30

    看看這個回答。 https://www.zhihu.com/questio...

    回覆
    0
  • 阿神

    阿神2017-04-18 10:49:30

    Java的引用(包括基本型別,物件引用型別)在宣告、方法呼叫等時候都會產生新的引用,複製等號右邊的引用。分為下面3種情況:

    1. 基本類型代表的值儲存在引用裡面,引用中專門有個區域儲存這個值,所以在複製的時候,值也同時被複製了。

    2. 引用型這個區域儲存的是物件在堆記憶體中的記憶體位址,引用複製的時候,指向的記憶體位址卻是同一份,所以不會涉及值(也就是物件)的複製

    3. 數組裡面都是儲存的引用(包括基本型,物件引用型別)


    引用資訊:在Java中,引用資料型別佔記憶體嗎?

    要弄清楚這個問題,首先要清楚,在JAVA中有四類八種基本類型,除了基本類型,全都是引用類型。例如你寫 int i = 1; 那麼它在記憶體裡的分配是這樣的:記憶體裡分配了一塊空間,這塊空間的名字是i,裡面的內容是1.

    當你使用i的時候就可以存取這塊空間裡的內容。而引用型別不同,引用型別在記憶體中佔兩塊記憶體。例如:你寫String s;或String s = null;這時候在記憶體裡分配一塊記憶體。這塊記憶體裝的是空值null,也就是什麼都沒有裝。因為還沒有進行初始化。上個圖:

    至於具體這個s分配在哪,要看他被聲明的位置。如果s被宣告為局部變量,那s就在堆疊空間。如果不是局部變量,那就不在堆疊上分配。而當你用s指向一個String類型的物件的時候,就改變了。也就是接著寫s = new String("zhihu");的時候。上個圖:

    原來的s裡面就會有一個值,根據s這塊空間裡的這個值就可以找到在堆上找到另一塊記憶體。所有new出來的東西都在堆記憶體裡。堆上的這塊記憶體裡對String的屬性進行分配。堆記憶體是動態分配記憶體的。所以既然是分配在堆上,其實也說明了new出來的物件佔多大記憶體並不能確定,只能在運作期間才能分配,才能明白這個物件分配多大。 而且佔用記憶體不能確定的原因還有一個就是,方法在執行的時候才分配記憶體。如果沒有呼叫方法,那方法只是一堆程式碼而已,不佔用記憶體。

    回覆
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-18 10:49:30

    謝謝大家的回答,都講的挺好的。我也明白了

    回覆
    0
  • 取消回覆