7

thisJavaでオブジェクトを構築する際にメソッドに引数として渡しても大丈夫ですか?

こうしようと思うと不安になるのですが、それが絶対に間違っているのかどうかはわかりません。次の架空の例を見てください。

public final class A {
    private final B b;
    private final List<String> words;

    public A(B b) {
        this.b = b;
        words = new ArrayList<String>();
        for(int i = 0; i < 10; i++) {
            words.add(b.getNextStringFromUser(this));
        }
    }

    public List<String> getWords() {
        return words;
    }
}

public class B {
    // returns a String chosen by the user based on the current state of A
    public String getNextStringFromUser(A a) {
        List<String> wordsSoFar = a.getWords();
        // ... omitted
    }
}

これを行うことが正しいことであると私が考えることができるケースは、コードの残りの部分の観点から不変である可能性があるオブジェクトを構築したい場合ですが、コンストラクターが状況に応じて異なるコースを取る可能性がある場合です。これまでに指定された状態について (部分的に構築されたオブジェクトの状態について話すことが理にかなっている場合)。上記の例では、ユーザーはこれまでに選択した文字列に基づいて文字列を選択し、それらがすべて選択されると、このオブジェクトが再び変更されることはありません。

この種のことはOK/お勧めですか?ありがとう。

4

5 に答える 5

2

特にマルチスレッド環境では、コンストラクターで「this」参照をリークすることは危険です。完全に構築されていないオブジェクトが他のスレッドから見えるようになる可能性があります。ただし、シングル スレッドから使​​用する場合は問題なく動作する可能性がありますが、この種のバグを見つけて修正するのは非常に困難です。したがって、IDE が警告としてマークしても驚かないでください。

于 2013-09-13T19:30:42.987 に答える
1

あなたが提示したシナリオでは、それは受け入れられません。

安全上の理由から、初期化されていない/部分的に初期化されたオブジェクトをできるだけ渡さないようにする必要があります。あなたの場合、次のように再宣言できgetNextStringFromUser(A a)ます。

public String getNextStringFromUser(List<String> wordsSoFar) {
        // ... omitted
}

さらに、相互に参照する必要がある 2 つのオブジェクトがあるシナリオは一般的ではありません。MVC Design PatternFactory Design Patternを確認すると役立つ場合があります。

これは同様の質問ですが、1 つのオブジェクトだけが他のオブジェクトへの参照を持っています。

于 2013-09-13T19:52:03.147 に答える
0

コードのthis問題は別のメソッドに渡されていません。問題は、コンストラクターでそれを行うことです。つまり、初期化が完了する前であっても、クラスが別のオブジェクトからアクセスされることを意味します。

于 2013-09-13T19:30:57.767 に答える