0

私は少しJava N00Bですが、クローンについてはかなり混乱しています。

次の間違ったクラスを検討してください

class blah {
   public blah(Collection<Integer> c){
       member_collection = c.clone(); //the clone here is defensive
   }
   private final Collection<Integer> member_collection;
}

やりたいことは明確だと思います。

clone() シンボルが見つからない理由を理解しています: clone は、コレクションのパブリックメソッドではありません。ただし、具体的なクラスではそれを使用したいので、コンパイラにそれを伝えたいだけです。

一般的なコレクションのクローンを作成したいと思ったのは私が初めてではないと思いますが、私が見たチュートリアルでは、問題を回避する方法ではなく、コレクションのクローンを作成できない理由を説明しているだけです。私は getClass() とキャストでハッキーなことを試しましたが、通常は醜い try-catch ブロックを作成する必要があり、正確に 1 つの初期化 (ポインター member_collection) が最終であることを確認するのは困難です!

私が本当にやりたいことは、何らかの形でその情報を型に入れることです。これを行う良い方法はありますか?

ありがとう!

4

3 に答える 3

3

次のようにコピーすることをお勧めします。

public class Blah {
    private final Collection<Integer> collection;

    public Blah(Collection<Integer> collection) {
        this.collection = new ArrayList<Integer>(collection);
    }
}

またはそのように:

public class Blah {
    private final Collection<Integer> collection = new ArrayList<Integer>();

    public Blah(Collection<Integer> collection) {
        this.collection.addAll(collection);
    }
}

これはあなたが試みていることと同じであり、与えられた順序Collectionが保持されることを保証します。

編集:与えられたものと同じ実装であることが絶対に必要で、設計を再考したくない場合は、ハッキーなリフレクションをいくつか実行して、staticメソッドに入れることができます。

public class Blah {
    private final Collection<Integer> collection;

    public Blah(Collection<Integer> collection) {
        this.collection = clone(collection);
    }

    @SuppressWarnings("unchecked")
    private static <T> T clone(T t) {
        try {
            Method cloneMethod = t.getClass().getDeclaredMethod("clone");
            return (T) cloneMethod.invoke(t);
        } catch (Exception ex) {
            // TODO Log ex
            return null;
        }
    }
}

具象コレクションcloneは public メソッドとして実装する必要があるため、ほとんどのコレクションでこれが機能するはずです。そうでない方向けになりますnull。代わりに、取得した例外を再スローしたい場合があります。

于 2012-09-19T20:31:07.703 に答える
2

あなたは Java の初心者なので、申し訳ありませんがclone()CloneableJava では と が壊れており、それらに依存するのは得策ではありません。ただし、clone()気になることだけが必要な場合は、次のことができます。

  1. プロジェクトにcommons-langを含める
  2. ObjectUtils.clone()/を使用しますObjectUtils.cloneIfPossible()(強く型付けされていませんが、かなり安全です)。

commons-lang を使用することは、とにかく悪い考えではありません。「JRE にあるはずの」ユーティリティのクラスとメソッドが多数含まれており、かなり標準的なものだからです。

于 2012-09-19T20:35:39.687 に答える
0

あなたはただ書くことができますmember_collection = new ArrayList<Integer>(c)

これにより、浅いコピーが作成されます。

于 2012-09-19T20:27:18.833 に答える