1
class Test {
    public static void main(String[] args) {
        int[] list = {1, 2, 3, 4, 5};
        reverse(list);
        for (int i = 0; i < list.length; i++) {
            System.out.print(list[i] + " ");
        }
   }

   public static void reverse(int[] list) {
       int[] newList = new int[list.length];

       for (int i = 0; i < list.length; i++) {
           newList[i] = list[list.length - 1 - i];
       }

       list = newList;
   }
}

このプログラムを実行すると、答えは 1 2 3 4 5 になります。この「逆」メソッドは 4 行目で呼び出されます。

4

5 に答える 5

1

問題は、Java パラメータの受け渡しが値渡しであることです。の最後のステートメントreverseは次のとおりです。

    list = newList;

残念ながら、はパラメーター (および値で渡される) であるため、この割り当てはメソッド内のlistの値には影響しません。listmain

reverseメソッドを適切に機能させるには、次のいずれかを行います。

  • 逆のリストを返すように変更する(そして結果をlistin に代入するmain)、または
  • listの対応するセルから のセルを割り当てるように変更しnewListます。

(ちなみに、その場で更新する場合は、別の配列listなしで実行できます。)newList


このコメントに応えて:

私が読んでいる本には、配列は参照によって渡され、メソッド内の配列に何が起こっても、メイン メソッド内の元の配列に影響すると書かれています。それとも、私の解釈が間違っていたのかもしれません!

その本が間違っているか、あなたがそれを誤解しています。(おそらく後者だと思います。) Java のすべての型 (つまり、すべての型) は、値によって渡され、値によって返されます。

少し紛らわしいのは、参照型の場合、渡される値または返される値がオブジェクトの参照であるということです。これにより、用語を誤解する余地が残ります (または、本が少しずさんになる可能性があります) が...

参照渡し」

... と ...

「参照を渡す」

...同じことを意味するわけではありません。

(後から考えると、Java オブジェクト ポインターを「参照」と呼ぶというゴスリングらの決定は、新しい Java プログラマーにとって混乱の原因です。OTOH、C および C++ から移行するプログラマーが古いものに固執していた場合、別の種類の混乱があったでしょう。用語「ポインター」)。

于 2013-05-23T15:37:47.817 に答える
1

問題は、Java が値によって配列への参照を渡すことです。つまり、reverse変更中の参照は呼び出し元のバージョンではなく、この呼び出しのためだけに作成されたコピーです。発信者には再割り当てが表示されません。

最終結果として、必要なだけ配列を変更できますが、呼び出し元に表示される方法で別の配列に置き換えることはできません。ラッパー クラスを作成する以外に、Java でそれを行う方法はありません。

完了したら、新しい配列を古い配列にコピーすることで、探している結果を得ることができます。ie: ではなく

list = newList;

行う

System.arraycopy(newList, 0, list, 0, list.length);

元の配列を常に変更したい場合は、元の配列を元に戻すこともできます。

public static void reverse(int[] list) {
    for (int i = 0, j = list.length - 1; i < j; ++i, --j) {
         int temp = list[i];
         list[i] = list[j];
         list[j] = temp;
    }
}

これにより、破棄するオブジェクトを作成することを回避できます。

しかし、与えられたものを常に変更するわけではなく、配列の逆コピーだけが必要になることが予想される場合は、代わりに新しい配列を返し、呼び出し元にそれをどうするかを決定させる方がよいでしょう。

于 2013-05-23T23:39:37.070 に答える