- - PR -
Object#clone()メソッドについて
1|2|3
次のページへ»
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2007-02-28 16:22
Object#clone()メソッドについて尋ねたいです。
Cloneableを実装した独自クラスを作成せずに、簡便にListやMapのclone()を実行する方法はないでしょうか? 下記のようなコードがあったとして、clone()可能ならば、clone()を呼び出すような方法はあるでしょうか。
独自で作成したinterfaceだったり、既存のinterfaceを拡張して、Cloneableを実装すれば、こと足りますし、 Listを内包するようなCloneableを実装したクラスを作成すればよいのは分かります。 いままでは、そうしてきたのですが、何だかすっきりしないもので。 私が知らないだけで、実はうまい実装方法があるのかと思い、尋ねてみました。 宜しくお願いいたします。 | ||||||||||||
|
投稿日時: 2007-02-28 16:30
java.util.Collections#copy()
なんてものでは要件は満たせないでしょうか? 使ったことがないのでちょっと自信ないです。 | ||||||||||||
|
投稿日時: 2007-02-28 16:38
三等兵さん 回答ありがとうございます。
回答頂いたのに、言葉が足りず、本当に申し訳ありません。 例として、java.util.Listをあげたのですが、 本当のところは、対象オブジェクトがクローン可能であれば、clone()を実行するようなコードが書きたいのです。 [ メッセージ編集済み 編集者: Guri 編集日時 2007-02-28 16:39 ] | ||||||||||||
|
投稿日時: 2007-02-28 17:13
ただclone()を実行して、どうするのですか ?
複製した別インスタンスが欲しいんじゃないんですか ? で、そういうときはコピーコンストラクタを利用/用意すると思いますが、どうでしょう ? 以上、「Effective Java」の受け売りです。 | ||||||||||||
|
投稿日時: 2007-02-28 17:14
使ったことはないのでどの程度使えるのか知りませんが、任意のObjectに対しObjectInputStreamに書き込んで復元すればとりあえずcloneしたことになるのでは?
ByteArrayOutputSteam bous = new ByteArrayOutputSteam(); ObjectOutputStream ous = new ObjectOutputStream(bous); ous.writeObject(object); ous.close(); ByteArrayInputSteam bins = new ByteArrayInputSteam(bous.toByteArray()); Object copy = new ObjectInputStream(bins).readObject(); java.util.ArrayListだとコピーできているようです。 [ メッセージ編集済み 編集者: だっちょ 編集日時 2007-02-28 17:24 ] [ メッセージ編集済み 編集者: だっちょ 編集日時 2007-02-28 17:26 ] | ||||||||||||
|
投稿日時: 2007-02-28 17:33
Cloneableはjavaの標準ライブラリの中でも、ワースト5に入るぐらいまずい設計だとおもいますが、どうしても必要なら、以下のようにリフレクションを使ってやるのがよいと思います。
このコードでは、呼び出し元はCloneNotSupportedExceptionをキャッチしなければならないので使い勝手が悪いですが、引数に渡すオブジェクトがclone可能であることが保障できる(そうでない場合は呼び出しもとのバグであるとする)場合は、CloneNotSupportedExceptionの代わりに非チェック例外であるIllegalArugumentExceptionやAssertionErrorを投げるのもありかと思います。 # 修正 # クローンの型チェックを追加。 # さらに、Class.castを使うように再修正。 [ メッセージ編集済み 編集者: sawat 編集日時 2007-02-28 18:12 ] | ||||||||||||
|
投稿日時: 2007-02-28 18:17
回答ありがとうございます。
ビシバシ様
意味がつかめないのですが、 私が書いた((Cloneable)list).clone();の部分のことでしょうか? これは、便宜上、Object obj = ((Cloneable)list).clone();を略しました。 それとも違う意図でしょうか。
ええ、独自に作成したクラスならば、そうするかもしれません。 だっちょ様 設計を変更して、お茶を濁しましたが、以前書いたコードでは、 こんな風に書こうとしました。
sawat様 reflectionがありましたか。。 参考になりました。 因みにワースト5の残り4つは何でしょうか。 私はSerializableを入れたいのですが。 今まで遭遇して最悪だったのが、java.awt.AlphaComposite(finalクラスなうえにSerializableを実装していない。writeObject()も実装できない。)をシリアライズしようとしたときです。 java.awt.GradientPaintもなかなかのものですが。 同じjava.awt.Paint実装クラスでもjava.awt.ColorはSerializableを実装しているのに。。 Serializableを実装し忘れているだけの気がするのですが。 [ メッセージ編集済み 編集者: Guri 編集日時 2007-02-28 18:18 ] | ||||||||||||
|
投稿日時: 2007-02-28 18:43
えーと、その辺はあまり具体的に考えずに書きました。 (つまり、そのぐらいイケてないCloneableは極力避けて通るべきだという意味) 個人的に気になるのを挙げるなら、
Serializableに比べればどれも実害は少なそうですね。 |
1|2|3
次のページへ»