2

私はJavaにかなり慣れていません。最近、Javaが値渡しであるという資料を読んでいました。自分でテストを実行する前に、この質問このブログを読みました。

さて、私の読書とクイックテストに基づいて、オブジェクト参照内に含まれる変数を変更する方法が2つあることがわかりました。次のアプローチのどれがより良いまたはより安全なアプローチですか?どちらのアプローチにも明らかな問題はありますか?

これらは両方とも「iArr[0]=45」を出力します。

アプローチ1:

public static void main(String args[] ){
   int[] iArr = {1};
   method(iArr) ;
   System.out.println( "iArr[0] = " + iArr [0] ) ;
}
public static void method(int[] n ) { 
    n [0] = 45 ;
}

アプローチ2:

public static void main(String args[] )
{
   int[] iArr = {1};
   iArr = method(iArr) ;
   System.out.println( "iArr[0] = " + iArr [0] ) ;
}
public static int[] method(int[] n ) { 
    n [0] = 45 ;
    return n;
}
4

2 に答える 2

2

2番目のアプローチは、エイリアスの可能性を開きます。

int[] n = {1};
int[] j;

j = method(n);
j[0] = 342;
System.out.println("iArr[0] = " + n[0]);
System.out.println("iArr[0] = " + j[0]);

印刷されます:

iArr[0] = 342
iArr[0] = 342

このため、私はこの状況で最初のアプローチを選択します。配列を変更するだけで、参照を返す必要はありません。必要に応じて、独自のエイリアスを作成することも簡単です。また、2番目のアプローチから、実際のパラメーター値を変更することも明確ではありません。これは非常に悪い習慣だと思います。

于 2012-06-21T23:17:11.357 に答える
2

どちらも同じ副作用を引き起こすため、どちらのアプローチも理想的ではありません。

つまり、これらは同じですが、2番目のアプローチでも変更されたオブジェクトが返されます。2番目のアプローチで、渡された配列オブジェクトが変更されます。iArrサンプルコードの#2からの戻り値の再割り当ては、変更されたオブジェクトに影響を与えません。Javaは(参照型に対して) Call-By-Object-Sharingセマンティクスを使用することに注意してください。戻り値はこの動作とは関係ありません。

アプローチ#2はこの事実を「隠す」ので(署名を見て「ああ、新しい配列オブジェクトを取得します!」と思います)、アプローチ#1は「汚い仕事をします」ので、実際には本当に嫌いですが、わかります。リターンタイプからすぐに。(一部の高度なケーシングでは、「チェーン」が役立つ場合があります。これはそれらの1つではありません。)void

副作用を引き起こさない簡単なバージョンを次に示します:(コードの推論とデバッグが容易になることが多いため、一般的に副作用を最小限に抑えることをお勧めします)。

public static void main(String args[] )
{
   int[] iArr = {1};
   int[] newArr = method(iArr) ;
   System.out.println( "iArr[0] = " + iArr [0] ) ;
   // This is different here, but it would "be the same" in the 
   // 2nd-case example in the post.
   System.out.println( "newArr[0] = " + newArr [0] ) ;
}
public static int[] method(int[] n ) {
    // This is a silly stub method, n would be presumably used.
    int[] x = new int[1];
    x[0] = 45; // modifying a DIFFERENT object
    return x;  // returning the NEW object
}
于 2012-06-21T23:22:12.480 に答える