17

foo(int i)Javaでメソッドを書いているとします。は値で渡されるため、 で変更しても安全
です。例えばifoo

void foo(int i) {
   私 = 私 + 1; // i を変更
   ...
}

Javaでメソッドの引数を変更することは良い習慣ですか、悪い習慣ですか?

4

6 に答える 6

23

一般的に悪い習慣と見なされていますが、他の回答でわかるように見落とす人もいます。

値によって直接渡されるプリミティブなどのパラメーターの場合、元の変数をオーバーライドしても利点はありません。この場合、@João の提案に従ってコピーを作成する必要があります。

参照が値 (オブジェクト) で渡されるパラメーターの場合、別のオブジェクトを指すようにハンドルを変更すると、まったく混乱します。パラメータとして渡されたオブジェクトの内容を変更すると、元のオブジェクトも変更されるため、これはなおさら重要です。

ハンドルによって参照されるオブジェクトを置き換えてからその内容を変更すると、呼び出し元の元の参照によって参照されるオブジェクトは置き換えられませんが、コードを読んでいる人は置き換えられると予想するかもしれません。

一方、オブジェクトを置き換えずにコンテンツを変更すると、メソッドを呼び出すメソッドはこの変更を予期しない場合があります。このカテゴリは通常、セキュリティ関連の悪い慣行に分類されます。

于 2012-08-18T16:05:27.283 に答える
8

これは単なる個人的な意見ですが、コードの後半で元のパラメーター値を使用したいと考えている他の人にとっては混乱を招く可能性があり、既に変更されていることに気付かない可能性があると思います。

さらに、単純に別の変数を作成し、それに変更された値 (つまりint j = i + 1) を代入する方が安上がりです。

于 2012-08-18T15:56:34.303 に答える
3

i は値で渡されるため、安全に変更できますfoo()

オブジェクト参照を渡す場合でも、オブジェクト参照はローカルであるため、完全に安全です。つまり、新しい参照をローカル参照に割り当てても、呼び出し元のコードの元の参照には影響しません。

それはあなたの個人的な選択です。ただし、このメソッドに渡された実際の値の追跡が失われる可能性があるため、引数の値は変更しません。

于 2012-08-18T16:02:37.260 に答える
2

注意すべき重要なことは、i = i + 1;i は実際には変わらないということです。のローカル コピーのみが変更されますi(つまり、i呼び出しコードの は変更されません)。

それに基づいて、読みやすさの問題であり、POLS (最小サプライズの原則)に準拠することにより、コード内の予期しない動作を回避します。

于 2012-08-18T15:57:37.210 に答える
1

中性。ただし、多くの人は、メソッドを次のように変更することをお勧めします。

void foo(final int i) {
    int j = i + 1; // not change i
    ...
}

どちらでも安心して働けます。

于 2012-08-18T15:57:39.590 に答える
1

コンテキストに依存します。私は、次の 2 つの理由から、「悪い習慣」に傾倒しています。

  1. 元の値が変更されていると思う人もいるかもしれません。
  2. コードの推論が難しくなる可能性があります (適切に短いメソッドで軽減されます)

3 つ目の問題は、参考値である場合に発生します。パラメーター参照を変更して別のものを指し、その状態を変更した場合、元の参照は変更されません。これは意図したものである場合とそうでない場合があります。パラメータへの別の参照を作成し、新しい参照の状態を変更すると、パラメータの参照変更されます。これ、意図したものである場合とそうでない場合があります。

于 2012-08-18T15:58:13.740 に答える