95

メソッド呼び出しで現在のオブジェクトを渡すことは、良い/悪い/許容できる慣行ですか。次のように:

public class Bar{
    public Bar(){}

    public void foo(Baz baz){
        //  modify some values of baz
    }
}

public class Baz{
    //constructor omitted

    public void method(){
        Bar bar = new Bar();
        bar.foo(this);
    }
}

具体的には、ラインはbar.foo(this)許容されますか?

4

10 に答える 10

166

それは何も悪いことではありません。まだ完全に初期化されていないオブジェクトへの参照を与えるため、コンストラクター内で同じことを行うことはお勧めできませ

ここに一種の同様の投稿があります: Javaはコンストラクターでこれを漏らし 、後者が悪い習慣である理由を説明します。

于 2013-07-03T07:17:55.787 に答える
156

それを使用しない理由はありませんthis。現在のインスタンスであり、使用することは完全に合法です。実際、それを省略するきれいな方法がないことがよくあります。

だからそれを使用してください。

例がなければ受け入れられると確信するのは難しいので (そのような質問に対する否定的な答えは常に議論しやすい)、最も一般的なjava.langクラスの1 つを開いたStringところ、もちろん、この使用のインスタンスを見つけました。

1084        // Argument is a String
1085        if (cs.equals(this))
1086            return true;

(this大規模な「承認済み」プロジェクトを探してください。必ず見つかります。

于 2013-07-03T07:16:28.427 に答える
42

はい。ただし、2 つの点に注意する必要があります。

  1. オブジェクトがまだ構築されていないときに これを渡す(つまり、コンストラクターで)
  2. これを存続期間の長いオブジェクトに渡すと、参照が存続し、このオブジェクトがガベージ コレクションされるのを防ぐことができます。
于 2013-07-03T09:50:26.100 に答える
13

それは完全に正常であり、完全に受け入れられます。

于 2013-07-03T07:16:48.120 に答える
4

同じ動作を実現するためのより単純な代替手段がある場合、メソッド呼び出しで現在のオブジェクトを渡すのは悪い習慣です。

定義により、あるthisオブジェクトから別のオブジェクトに渡されるとすぐに、双方向の関連付けが作成されます。

Martin Fowler による Refactoring を引用すると、次のようになります。

双方向の関連付けを単方向に変更 (200)

双方向の関連付けは便利ですが、代償が伴います。その代償は、双方向リンクを維持し、オブジェクトが適切に作成および削除されるようにするための追加の複雑さです。双方向の関連付けは多くのプログラマーにとって自然ではないため、エラーの原因となることがよくあります

...

必要な場合は双方向の関連付けを使用する必要がありますが、そうでない場合は使用しないでください。双方向の関連付けが重みを失っていることがわかったらすぐに、不要な端を削除します。

したがって、理論的には、合格する必要があると判断したときは警鐘を鳴らし、this目の前の問題を解決するための他の方法を真剣に考えなければなりません。もちろん、最終的にそうすることが理にかなっている場合もあります。

また、全体的な改善のためのコードの長期的なリファクタリング中に、「悪い習慣」を実行して一時的に設計を破損する必要があることがよくあります。(一歩後退、二歩前進)。

実際には、疫病のような双方向リンクを回避することで、コードが大幅に改善されていることがわかりました。

于 2013-07-03T17:00:21.097 に答える
4

はい。あなたはそれを使うことができます。プログラミングでは合格するのが一般的ですthis。しかし、それを使用することには長所と短所があります。それでも、そうするのは危険ではありません。

于 2013-07-03T07:17:16.897 に答える
2

thisパスが正しく、優れた設計に従っているもう 1 つの例を追加するだけです: Visitor pattern。Visitor デザイン パターンでは、メソッドaccept(Visitor v)は通常、単に を呼び出す方法で実装されますv.visit(this)

于 2013-07-10T06:15:25.453 に答える
1

許容できる

Oracle JAVA ドキュメントからのスニペット:

インスタンス メソッドまたはコンストラクター内では、これは現在のオブジェクト (メソッドまたはコンストラクターが呼び出されているオブジェクト) への参照です。this を使用して、インスタンス メソッドまたはコンストラクター内から現在のオブジェクトの任意のメンバーを参照できます。

これをフィールドで使用する

this キーワードを使用する最も一般的な理由は、フィールドがメソッドまたはコンストラクターのパラメーターによって隠されているためです。

于 2013-07-03T07:20:01.253 に答える