14

Java のメソッドで変数の値を変更することについて質問があります。

これは私のコードです:

public class Test {
    public static void funk(int a, int[] b) { 
        b[0] = b[0] * 2; 
        a = b[0] + 5;
    } 

    public static void main(String[] args) {
        int bird = 10;
        int[] tiger = {7};

        Test.funk(bird, tiger);
    }
}

メソッドの実行後、Test.funk(bird, tiger)bird の値は変更されません。メソッドで値を変更して10も、値はそのままです。funk()a = b[0] + 5;

一方、ステートメントがあるため、配列内の要素の値は変更されます。b[0] = b[0] * 2;

なぜ一方が変化し、もう一方が変化しないのか理解できませんか?誰かが私のためにこれを説明してもらえますか.

4

4 に答える 4

18

これについては、Jon Skeet のParameter-Passing in Javaに関する記事を参照してください。

要するに (全体的な説明については、彼のサイトを参照してください):

配列は参照型です。配列を指す参照を渡すと、参照の値がコピーされ、関数のパラメーターに割り当てられます。したがって、パラメーターは、渡された引数と同じ配列を指します。したがって、関数のパラメーターを介して配列に加えた変更は、呼び出し元の関数で表示されます。ただし、パラメーター (b) をnullに設定するなどして、パラメーター自体 (b) を変更しても、パラメーター (b) は渡された引数 (tiger) のコピーにすぎないため、呼び出し元の関数には通知されません。

整数はいわゆるプリミティブ型です。整数を渡すと、その値がコピーされ、パラメーターにも割り当てられます。ただし、その値は実際のデータへの参照ではなく、データそのものです。そのため、関数内のパラメーターへの変更はパラメーター (a) に影響しますが、呼び出し元の関数 (bird) に渡される引数には影響しません。

于 2009-01-28T23:45:00.523 に答える
4

基本的に、オブジェクト (配列など) は「参照によって」メソッドに渡されます。したがって、オブジェクトを変更すると、メソッドに渡された同じオブジェクトが変更されます。

プリミティブ (int など) は「値で渡される」ため、a で値を割り当てる変数は、渡された int 変数と同じではありません。

これが役立つことを願っています...

于 2009-01-28T23:49:20.593 に答える
4

それはあなたが宣言するときだからです

 public static void funk(int a, int[] b) 

変数aのスコープはそのメソッドだけです。次に、値を変更すると、そのメソッドのその変数の値のみが変更されます。

Bについて。これは、メインで作成された同じ配列への新しいオブジェクト参照です。そのため、値が変化しているように見えます (変化しているのは、その下の配列オブジェクトです)

しかし、これを試してください:

public static void funk(int a, int[] b) { 
    // create a new reference for b
    int[] c = new int[b.length];
    c[0] = b[0];
    b = c;

    // The same.
    b[0] = b[0] * 2; 
    a = b[0] + 5;
} 

これを行うと、 tiger の値も変更されません ( funk で作成された新しい配列 c の内容のみ)。

ラッパーを使用して ref によるパスをシミュレートできます。この投稿を参照してください。

それについてのコメントはありませんが、

編集楽しみのために:

上記のラッパーを使用するようにコードを変更しました。

それはかなり奇妙に見えますが、うまくいくようです。

// By ref simulated.
public class Test {

    public static void funk(_<Integer> a, int[] b) { 
        b[0] = b[0] * 2; 
        a.s(  b[0] + 5 ) ;
    } 

    public static void main(String[] args) {
        _<Integer> bird = new _<Integer>(10);
        int[] tiger = {7};

        Test.funk( bird , tiger );

        System.out.println("bird = " + bird );
        System.out.println("tiger = " + tiger[0] );

    }

}

版画

bird = 19
tiger = 14

:-S

于 2009-01-28T23:47:39.100 に答える
0

1つの変数は参照渡しで、もう1つは値渡しです:)

参照渡しと値渡しの違いは何ですか?

于 2013-11-09T15:30:16.217 に答える