検索

ホームページ  >  に質問  >  本文

关于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_lee2804日前560

全員に返信(6)返信します

  • PHPz

    PHPz2017-04-18 10:49:30

    swapEqual(int[] a,int[] b):
    先頭:
    a --> {1,2} (アドレス 1)
    b --> (アドレス 2)
    コードによる処理後 (a と b が指すアドレスが交換されます):
    b --> {1,2} (アドレス 1)
    a --> (アドレス 2)
    ただし、c、d、c、d には影響しません:
    c --> {1,2} (アドレス 1)
    d --> (アドレス 2)

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

    swap(int[] a,int[] b):
    先頭:
    a --> {1,2} (アドレス 1)
    b --> (アドレス 2)
    コードによる処理後 (アドレス 1 と 2 の値が交換されます):
    a --> {3,4} (アドレス 1)
    b --> (アドレス 2)
    そうではありませんが、c と d が指すアドレスには影響しますが、元のアドレスの下の値は変更されています:
    c --> {3,4} (アドレス 1)
    d --> } (アドレス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 には 4 つのカテゴリと 8 つの基本型があり、基本型を除いて、それらはすべて参照型であることを理解する必要があります。たとえば、int i = 1;と書くと、メモリ内での割り当ては次のようになります。メモリ内にスペースが割り当てられ、このスペースの名前はi、内部のコンテンツは1です。

    iを使用すると、このスペースのコンテンツにアクセスできます。参照タイプが異なります。参照タイプはメモリ内の 2 つのメモリ ブロックを占有します。たとえば、 String s または String s = null と書き込むと、メモリの一部がメモリに割り当てられます。このメモリには null 値がロードされます。これは、何もロードされないことを意味します。まだ初期化されていないので。前の写真:

    この s がどこに割り当てられるかについては、宣言された場所によって異なります。 s がローカル変数として宣言されている場合、s はスタック空間にあります。ローカル変数ではない場合、スタックには割り当てられません。ただし、 s を使用して String 型のオブジェクトを指すと、何かが変わります。つまり、次に s = new String("zhihu"); と書くときです。前の写真:

    元の s には値が存在します。s の空間内のこの値に基づいて、ヒープ上の別のメモリを見つけることができます。新しいものはすべてヒープ メモリ内にあります。文字列属性はヒープ上のこのメモリに割り当てられます。ヒープ メモリは動的に割り当てられるメモリです。したがって、オブジェクトはヒープ上に割り当てられるため、実際には、新しいオブジェクトがどれだけのメモリを占有するかが不明であることを意味します。オブジェクトがどれだけの大きさで割り当てられているかを理解するには、実行時にのみ割り当てることができます。 占有メモリを特定できないもう 1 つの理由は、メソッドが実行時にのみメモリを割り当てることです。メソッドが呼び出されない場合、メソッドは単なるコードの集まりであり、メモリを占有しません。

    返事
    0
  • 伊谢尔伦

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

    皆さん、ご回答ありがとうございます。どれもとても良いものでした。私も分かりました

    返事
    0
  • キャンセル返事