1

最近、Java 開発者の役割のインタビューで、クラス B のオブジェクトであるメンバー変数があり、クラス B がプロジェクトの外部にあり、編集できない状況で、クラス A を不変にする方法を尋ねられました。さらに、プログラマーはクラス B に、別のユーザー定義クラスのオブジェクトである独自のメンバー変数を持つことさえあります。よく考えて、クラス B がディープ クローン自体のメソッドを実装して公開しない限り、方法はないとインタビュアーに伝えました。

しかし、インタビュアーは納得していませんでした。そのようなクラスを不変にする方法は本当にありますか?

私の記憶が正しければ、これが彼が説明した状況でした。彼は私にクラス A を不変にすることを望んでいました。

final public class A {
    final private B b;

    A(B b) {
        this.b = b; // Class b might/might not be cloneable
        // this.b = (B)b.clone();
    }

    public B getB() {
        return b;
        // return (B)b.clone();
    }
}

class B // external cannot edit
{
    C c;

    public C getC() {
        return c;
    }

    public void setC(C c) {
        this.c = c;
    }
}

class C // external cannot edit
{
    int i;
    String j;

    public int getI() {
        return i;
    }

    public void setI(int i) {
        this.i = i;
    }

    public String getJ() {
        return j;
    }

    public void setJ(String j) {
        this.j = j;
    }
}
4

2 に答える 2

2

B を世界に公開しないでください。したがって、B を返すメソッドはありません。

代わりに、B を変更しない B のメソッドを特定し、b で同じメソッドを呼び出して A にこれらのメソッドを実装させます。

したがって、B にメソッド calcSomething() がある場合、a には b.calcSomething() を返すだけの calcSomething() メソッドが必要です。

于 2015-11-30T18:39:21.407 に答える
0

次のようなものを使用できます。

final public class A {
    final private B b;

    A(B b) {
        this.b = cloneB(b); 
    }

    public B getB() {
        return cloneB(b);
    }

    private static B cloneB(b){ 
        B newB = new B(); 
        C c = new C();
        c.setI(b.getC().getI());
        c.setJ(b.getC().getJ());
        newB.setC(c); 
        return newB;
    }
}

その場合、クラス A は 100% 不変です。

更新: また、リフレクションまたはシリアル化を使用して、クラスのディープ コピーを取得することもできます (クラスに深い階層がある場合)。たとえば、シリアル化に GSON を使用します。

private static B cloneB(b){ 
    String tmp = new GSON().toJson(b);
    return new GSON().fromJson(tmp, B.class);
}

など

于 2015-11-30T18:52:41.767 に答える