3
public class TestArray {
    public static void main(String[] args) {
        int[] ar = {1,2,3,4,5,6,7,8,9};

        shiftRight(ar);
        for (int i = 0; i < ar.length; i++) {
            System.out.print(ar[i]);
        }
        // prints: 912345678 -- good
        System.out.println();

        reverseArray(ar);
        for (int i = 0; i < ar.length; i++) {
            System.out.println(ar[i]);
        }
        // prints: 91234567 -- I don't understand       
        System.out.println();       
    }
    public static void shiftRight(int[] ar) {
        int temp = ar[ar.length - 1];
        for (int i = ar.length - 1; i > 0; i--) {
            ar[i] = ar[i - 1];
        }
        ar[0] = temp;
    }
    public static void reverseArray(int[] ar) {
        int[] temp = new int[ar.length];
        for (int i = 0, j = temp.length - 1; i < ar.length; i++, j--) {
            temp[i] = ar[j];
        }
        ar = temp;
        for (int i = 0; i < ar.length; i++) {
            System.out.print(ar[i]);
        }
        // prints: 876543219
        System.out.println();
    }
}

配列をパラメーターに渡すと、配列への参照がパラメーターに渡されます。メソッド内で配列パラメーターが変更された場合、その変更はメソッドの外部に表示されます。

最初のメソッド はshiftRight、私が期待していることを実行します。メソッドの外側で配列を変更します。

ただし、2 番目のメソッドは、メソッドの外部で配列を変更しません。ただし、メソッド内で for ループを実行すると、正しい値が出力されます。arの参照が を指していないのはなぜtempですか? メソッドが停止したときに変数tempが破棄されるためですか?それによって参照も削除されますか? その場合でも、なぜ Javaarは の参照を指していた を取得し、それをtempの元の参照に再適用するのarでしょうか?

ありがとうございました。

4

4 に答える 4

4

Java では、オブジェクトが参照によって渡されると言うのは誤りです。オブジェクトへの参照は値渡しであると言ったほうが正確です。

配列参照をreverseArray値で渡します。local パラメータは、配列への参照のコピーです。後であなたが言うとき

ar = temp;

からの元の配列参照ではなく、ローカル arのみを指しています。temparmain

一方、shiftRightメソッドでは、コピーされた参照を介して配列に直接アクセスしたため、元の配列の内容が変更され、メソッドは期待どおりに機能します。

于 2013-07-11T22:35:25.603 に答える
0

temp の値を ar に代入すると、

ar = temp;

メソッドの引数のポインターをその値に設定します。これにより、メイン メソッドの ar の参照が変更されることはありません。

変更を「固定」したい場合は、そのメソッドから値を返し、次のようにメインに割り当てます。

public static void main(String[] args) {
    int[] ar = {1,2,3,4,5,6,7,8,9};

    ar = reverseArray(ar);
    System.out.println();       
}

public static int[] reverseArray(int[] ar) {
    int[] temp = new int[ar.length];
    for (int i = 0, j = temp.length - 1; i < ar.length; i++, j--) {
        temp[i] = ar[j];
    }
    ar = temp;
    for (int i = 0; i < ar.length; i++) {
        System.out.print(ar[i]);
    }
    // prints: 876543219
    System.out.println();

    return ar;  // might as well return temp
}
于 2013-07-11T22:43:40.743 に答える
0

問題は、ローカル変数temp配列を作成し、 を設定することですar=temp。新しいローカル配列を作成してコピーした変数をar指すのではなく、実際にの内容を変更する必要がありますartemp

このようなことを試してください。

public static void reverseArray(int[] ar) {
    int[] temp = new int[ar.length];
    System.arraycopy( ar, 0, temp, 0, ar.length );
    for (int i = 0, j = temp.length - 1; i < ar.length; i++, j--) {
        ar[i] = temp[j];
    }

    for (int i = 0; i < ar.length; i++) {
        System.out.print(ar[i]);
    }
    // prints: 876543219
    System.out.println();
}
于 2013-07-11T22:33:03.400 に答える
0

reverseMethod配列への独自の参照を受け取り、呼び出し元の参照に触れることはできません。

つまり、参照を値で受け取ります。それを保持するローカル変数に新しい値を格納することを選択した場合、それは問題ありませんが、古い値への参照が格納される可能性のある他の場所には影響しません。

于 2013-07-11T22:35:19.667 に答える