10

コンストラクターで作成されたオブジェクトへの参照を維持するための良い方法はありますか?それは、拡張クラスのスーパーコンストラクターに渡す必要があります(スーパークラスからアクセスできるようにするか、パラメーターとしてコンストラクターに渡す以外)?

例を挙げて明確にしましょう。このクラスを取得します(これは変更できず、fooへのアクセスも許可されません):

class TestA {
    TestA(Object foo) {}
}

ここで、このクラスを次のように拡張したいと思います。

class TestB extends TestA {
    Object myCopyOfFoo;

    TestB() {
        super(new Object());
    }
}

new Object()で作成したものを保存する良い方法はありmyCopyOfFooますか?

これらの3つのアイデアのいずれも機能しません。

TestB() {
    myCopyOfFoo = new Object();
    super(myCopyOfFoo);
}

(エラー:コンストラクター呼び出しはコンストラクターの最初のステートメントである必要があります)

TestB() {
    super(myCopyOfFoo = new Object());
}

(エラー:コンストラクターを明示的に呼び出している間は、インスタンスフィールドmyCopyOfFooを参照できません)

TestB() {
    super(makeFoo());
}

Object makeFoo() {
    myCopyOfFoo = new Object();
    return myCopyOfFoo;
}

(エラー:コンストラクターを明示的に呼び出している間はインスタンスメソッドを参照できません)

私は次のことができると思いますが、それはスレッドセーフでもエレガントでもありません:

static Object tempFoo;

TestB() {
    super(tempFoo = new Object());
    myCopyOfFoo = tempFoo;
}

誰かが私のためにもっと良いアイデアを持っていますか?そして、なぜ私の最初の2つのアイデアが合法ではないのですか?

4

3 に答える 3

19

どうですか:

class TestB extends TestA {
    Object myCopyOfFoo;

    // I assume you actually wanted this to take a parameter called foo?
    // I've left it as per the question...
    TestB() {
        this(new Object());
    }

    private TestB(Object copy) {
        super(copy);
        myCopyOfFoo = copy;
    }
}

2番目のコンストラクターはプライベートであるため、同じクラス(またはそれを囲むクラス)内でのみ呼び出すことができます。したがって、最初のコンストラクターと同様に、2番目のコンストラクターを呼び出すものが適切なコピーを作成したことを確認する必要があります。

編集:あなたの実際の状況があなたが既存のパラメータのコピーを取っているということであるならば、これはうまくいくでしょう...

class ClassB extends ClassA {
    private final Foo copyOfInput;

    ClassB(Foo input) {
        super(input = input.clone());
        copyOfInput = input;
    }
}

それはかなり醜いですが:(

于 2012-10-04T22:51:25.960 に答える
1

別のオプション:

public class TestB extends TestA {

    Object myCopyOfFoo;

    private TestB(Object foo) {
        super(foo);
        myCopyOfFoo = foo;
    }

    public static TestB createInstance() {
        Object foo = new Object();
        return new TestB(foo);
    }

}
于 2016-01-11T09:39:31.147 に答える
0

次はどうですか:

class TestB extends TestA {
    Object myCopyOfFoo = new Object();

    TestB() {
        super(myCopyOfFoo);
    }
}

オブジェクトは、新しいオブジェクトTestBを作成するときにのみ初期化されるので、本質的に、これはあなたが望むことをしますか?

于 2012-10-04T22:54:39.173 に答える