web-dev-qa-db-ja.com

メソッドの変数の値を変更するJava

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の値は変更されません-funk()メソッドで値を変更した場合でも、値_10_のままです。 _a = b[0] + 5;_

一方、_b[0] = b[0] * 2;_というステートメントがあるため、配列内の要素の値が変化します。

なぜ一方が変化し、もう一方が変化しないのか理解できません。誰かがこれについて私に説明してくれませんか。

14
user42155

これについて説明している Javaでのパラメーター渡し に関するJon Skeetの記事をご覧ください。

要約すると(より詳細な説明については彼のサイトを見てください):

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

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

宣言すると

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

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

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

4
OscarRyz

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

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

これがお役に立てば幸いです...

4
stephendl

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

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

0
kjv.007