2009-07-06 19 views
10

Javaのコピーコンストラクタ/ファクトリメソッドなどの推奨または確立されているベストプラクティスと命名規則は誰にもありますか?特に、クラスThingがあり、Thingと同じ値(またはインスタンスメソッドの場合はインスタンス)として新しいThingを返すメソッドが必要です。これをコンストラクタまたは静的ファクトリメソッドまたはインスタンスメソッドとして使用しますか?あなたはそれを何と呼びますか?もしあなたがJavaでクローンしなければ、あなたは何をしていますか?それを何と呼んでいますか?

タイトルごとに、私はclone()Cloneableを避けたいと思います。

+0

なぜあなたはclone()とCloneableを避けたいですか? –

+0

@Thomas Owens、ここをクリックしてください。http://www.artima.com/intv/bloch13.html – Yishai

+0

解決策としてコピーコンストラクタを回答すると、コピーコンストラクタはすべてのケースを適切に処理しません。例えば、あなたが具体的なクラスを知らないとき(ただし、あなたはまだクローン/コピー/ whateveryoucallitメソッドの中でコピーコンストラクタを使うことができます)。 –

答えて

0

必要に応じてclone()のメソッドを上書きすることができます。もう1つの使用法は、このタイプのオブジェクトを取るコンストラクタです。つまり、new ArrayList(anotherList)です。

3

私はそれをコピーメソッドまたはコピーコンストラクタ(場合によっては)と呼びます。それが静的メソッドであれば、それをファクトリと呼びます。

何をすべきかという点で、最も柔軟で長い生活のオプションはコピーコンストラクタです。これにより、サブクラスは親のように自分自身をコピーすることができます。あなたは、Cloneableを実装して、あなたはいくつかのオプションを持って、それを

Thing copy = new Thing(copy from me); 
2

私はその後、コンストラクタ

... 
public Thing(Thing copyFrom) 
{ 
    attr1 = copyFrom.attr1; 
    attr2 = copyFrom.attr2; 
    //etc... 
} 

にしてくださいコピー操作の内容を記述する名前を持つメソッド(静的またはインスタンス)を使用することです。深いコピーや浅いコピーなどです。

0

をクローンコピーコンストラクタが、私の好ましい方法を追加したいとき

15

実効Java Recom mends以下のいずれか:(他の人が述べたように)

  1. コピーコンストラクタ:

    パブリック項目(商品アイテム)

  2. コピーファクトリメソッド:

    パブリック静的アイテムnewInstance(アイテムアイテム)

(また、不変体のコピーはありません)

主な違いは、#1では結果の実際のクラスを選択し、#2では実装者がサブクラスを返すことができる点です。クラスのセマンティクスによって、どちらが最適かを知ることができます。

0

immutable data structuresを使用してください。 clone()が必要だと感じる唯一の理由は、あなたのオブジェクトを変えていることです。あんな事はしないで。あなたができることを考える:

  • あなたのクラスを最終的にしてください。
  • クラス内のフィールドを最終的かつ非公開にします。

    public Vector3D setX(double x) { 
        return new Vector3D(x, this.y, this.z); 
    } 
    

    は、だから私は、私が言っているものを推測する私の代わりに突然変異のコピーコンストラクタを使用して、I ...さ:

例えば、ここでは不変3次元ベクトルオブジェクトのための「セッターは」です変更したい属性に基づいて名前を付けるだけです。

0

別のオプションは、例えば、ソースオブジェクトにコピーする方法を実装することです:

interface Has3DCoords { 
    void setLocation(double x, double y, double z); 

    void copyCoordsTo(Has3DCoords dest); 
} 

あなたは、その後のようなコードの切れ端でコピーを実装します:

class Thing implements Has3DCoords { 
    private Point3D loc; 
    // ... 

    void setLocation(double x, double y, double z) { 
     loc.setLocation(x, y, z); 
     // or: loc = new Point3D(x, y, z); 
    } 

    void copyCoordsTo(Has3DCoords dest) { 
     loc.copyCoordsTo(dest); 
     // or: dest.setLocation(loc.getX(), loc.getY(), loc.getZ()); 
    } 

    OtherThing createOtherThing() { 
     OtherThing result = new OtherThing(); 
     this.copyCoordsTo(result); 
     return result; 
    } 
} 

これをすることができ次の場合に便利です:

  • オブジェクト全体を複製するのは意味がありませんそう頻繁に一つのユニットとしてコピーされ、関連するプロパティのグループがあり
  • あなたはThing
  • プロパティの数が多いのプロパティとしてlocを公開したくない(または多くのそのようなグループがあります)それらのすべてをパラメータとして必要とするコンストラクタは扱いにくいでしょう。
0

これは、オブジェクトをコピーする素敵なアプローチではなく、あなたが直列化オブジェクトの深いコピーを実行したい場合は、次のは時々便利です。これにより、コピーコンストラクタを記述したり、Cloneableを実装したり、ファクトリクラスを記述する必要がなくなります。

ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
ObjectOutputStream oos = new ObjectOutputStream(bos); 

//Serializes the input object 
oos.writeObject(input); 

ByteArrayInputStream bais = new ByteArrayInputStream(bos.toByteArray()); 
ObjectInputStream ois = new ObjectInputStream(bais); 

//Copy of the input object 
Object output = ois.readObject(); 

例外を処理してストリームをうまく閉じることを忘れないでください。

関連する問題