2

私は興味を持ってこの質問を読みました: Javaで参照によってパラメーターを渡すことはできますか?

出てくるのは、パラメータ(プリミティブではない)が参照値をコピーすることによって渡されるということです。そして、例が示すように、指定したパラメータの参照を変更することはできません。

Object o = "Hello";
mutate(o)
System.out.println(o); // Will print Hello

private void mutate(Object o) { o = "Goodbye"; } //NOT THE SAME o!

finalこの種の問題は、次のように使用することで回避できます。

private void mutate(final Object o) { o = "Goodbye"; } //Compilation error

質問 :

  • このような場合のキーワードはfinal、コンパイルエラーをスローするためにのみ使用されますか?
  • 最終的に、指定されたパラメーターの参照を変更できない場合、final暗黙的または必須ではないのはなぜですか?

Javaでメソッドパラメータを使用することはめったにありませんが、メソッドパラメータfinalを自発的に省略してしまうケースは考えられませんfinal

ありがとう!

4

5 に答える 5

4

これを回避するには:

public void searchBiggest(String startingWith) {
    for (String s : collection) {
        if (s.startsWith(startingWith)) {
            startingWith = s;
        }
    }
    return startingWith;
}

ご覧のとおり、パラメーターが渡した値とは異なる値を保持している可能性があるため、コードが直感的ではなくなります。

ハードコアJavaから-第2章:

このような小さなバグは、見つけるのが最も難しいことがよくあります。マーフィーの法則により、このコードがプロジェクトの巨大な部分の真ん中にあることを絶対に保証でき、エラーレポートが直接ここにつながることはありません。さらに、バグが本番環境に移行してユーザーが修正を求めて叫ぶまで、バグの影響に気付かない可能性があります。

コードを書いたら、話は終わっていないことを忘れるわけにはいきません。人々はあなたのコードに変更、追加、エラーを加えるでしょう。コードを調べて、混乱したものをすべて修正する必要があります。この問題の発生を防ぐには、次の手順を実行します。

同様のサンプルは、パラメーターを使用して実行され、さらにパラメーターを使用して他のメソッドを呼び出します(既に変更されています)。

于 2012-07-31T09:06:14.850 に答える
3

私は通常、この参照の偶発的または意図しない変更を防ぐためにこれを行います。例えば

private String doSomething(final String arg) {
   // final to prevent me doing something stupid!
}

興味深いシナリオの1つは、セッターです。で渡された引数ではなく、メンバー変数を設定していることを確認する必要があります。例えば

public void setArg(String arg) {
   _arg = arg;
}

上記のシナリオでは、メソッドパラメータが最終的でない場合は、次のように設定できます。

   arg = arg;

間違って。上記は一般的なタイプミスであるか、検索/置換リファクタリングが原因で発生する可能性があります。ファイナルにすることargで、誤って再割り当てすることはありません。

于 2012-07-31T09:01:26.107 に答える
3

見つけにくいバグが発生する可能性があるため、通常はパラメータを変更しないでください。ただし、役立つイディオムや状況がいくつかあります。

public void print(String msg, int count) {
    msg = (msg != null)? msg : "Default";
    while(--count >= 0) {
        System.out.println(msg);
    }
}
于 2012-07-31T09:05:01.553 に答える
2

1.メソッドを呼び出してメソッドを呼び出したときにObject Reference Variable、引数としてを渡します。

    mutate(o);

2.メソッド定義でfinalキーワードを使用することにより、finalになりました。つまり、 Object型のローカルオブジェクト参照変数finalであるため、この変数を使用して他のオブジェクトを指すことはできません。Parameter o

注:Object Reference Variableこれはfinal、HEAP上のオブジェクトではありません)

mutate(final Object o)

3.オブジェクト参照変数oに関連付けられているオブジェクトを、他のオブジェクト参照変数に割り当ててから変更することができます。

Object i = o;
 i = "GoodBye";
于 2012-07-31T09:12:39.440 に答える
2

Javaは値を渡します。したがって、mutateを呼び出すと、oのコピーが渡されます。

次に、mutate内で、oのコピーが「Goodbye」を指すように設定されます。元のoは変更されていません。

パラメータをfinalに設定してもこれは変更されませんが、これまで見てきたように、元の参照のコピーの再割り当ては停止します。ただし、これは元の参照の再割り当てを停止することと同じではありません。

于 2012-07-31T09:03:52.900 に答える