プロトタイプモデルは -プロトタイプオブジェクトのインスタンスを作成し、プロトタイプをコピーして新しいオブジェクトを作成するために、指定された型を指します。呼び出し側は、作成のいずれかの詳細を知る必要はありませんコンストラクタを呼び出すことはありませ!これは、スキーマを作成属します。
これは、新しい通じ、すでに道他のオブジェクトのコンストラクタを使用せずに作成したテンプレートなどのオブジェクトのメモリによるものです。
直接十分に、その実装を気にしないので、上のJDK複製可能なインターフェース(深いクローンへの道)を達成して、、々BeanUtilsに、グアバJSON実装の多くのプロトタイプモデルがありました。
深いと浅いクローンクローンに分け!
浅いクローン:コピーオブジェクトへの参照である、それは、コピーされたオブジェクトの値も変更されます、元のオブジェクトの値が変更を言うことです。
ディープクローニング:オブジェクトを作成するには、バイトコードを構築することにより、オブジェクトの値をコピーします。
ここで、春の構成はまた、通常、ほとんどの浅いクローンと、一般的に浅いクローンによって達成されます。
これはシングルトンパターンの競合。あなたはそれを作成するオブジェクトを使用するたび場合は、同じオブジェクトを使用することができますたびに、あなたはプロトタイプモデルを使用する必要がない場合、あなたは、プロトタイプモデルを使用することができます!
例浅いクローン -
プロトタイプのプロトタイプインタフェースを作成します。
パッケージcom.pansoft.com.prototype。 パブリック インターフェースプロトタイプ{ プロトタイプクローン(); }
オブジェクトのConcretePrototypeのクローンを作成するための特定の必要性を作成します。
パッケージcom.pansoft.com.prototype。 輸入はjava.util.List; パブリック クラス ConcretePrototypeAは実装したプロトタイプ{ プライベート int型の年齢を、 プライベート文字列名; プライベートリストの趣味。 公共 int型getAge(){ 戻り値の年齢。 } 公共 ボイド setAge(int型の年齢){ この .age = 年齢。 } パブリック文字列のgetName(){ 戻り名。 } 公共 のボイドsetName(文字列名){ この .nameの= 名前。 } パブリックリストgetHobbies(){ 戻り趣味。 } 公共 ボイドsetHobbies(リスト趣味){ この .hobbiesの=の趣味。 } パブリックプロトタイプクローン(){ ConcretePrototypeA concretePrototypeA = 新しいConcretePrototypeA()。 concretePrototypeA.setAge(この.age)。 concretePrototypeA.setName(この.nameの); concretePrototypeA.setHobbies(これは.hobbies)。 リターン ヌル。 } }
これはプロトタイプのインタフェース、クラスのConcretePrototypeAクローン方法に大きな実装クローン()メソッドは、新しいオブジェクトを継承します。
Clientオブジェクトの作成:
パッケージcom.pansoft.com.prototype。 パブリック クラスクライアント{ / * プライベートプロトタイプのプロ。 公共のクライアント(プロトタイププロ){ this.pro =プロ。 } * / パブリックプロトタイプstartClone(プロトタイプconcretePrototype){ 戻り)(concretePrototype.cloneします。 } }
それには、プロトタイプ・インターフェース・オブジェクトを介してcloneメソッドを呼び出します。
テスト:
パッケージcom.pansoft.com.prototype。 輸入はjava.util.ArrayList; 輸入はjava.util.List; パブリック クラスprototypeTest { 公共 静的 ボイドメイン(文字列[]引数){ ConcretePrototypeA concretePrototype = 新しいConcretePrototypeA()。 concretePrototype.setAge( 18 )。 concretePrototype.setName( "トム" ); リスト趣味 = 新しいのArrayList <文字列> (); concretePrototype.setHobbies(趣味)。 クライアントクライアント = 新しいですクライアント(); ConcretePrototypeAコピー = (ConcretePrototypeA)client.startClone(concretePrototype) のSystem.out.println(コピー) するSystem.out.println( "クローンオブジェクト参照型のアドレス値:" + copy.getHobbies()) ; のSystem.out.println(「元のオブジェクトの参照型のアドレス値:」+ concretePrototype.getHobbies()); // 等しい、コピーの値が記載されていないが、浅いクローンであるアドレス。 // このように一定のリスクがある のSystem.out.println( "オブジェクト・アドレス比較:" +(copy.getHobbies()== concretePrototype.getHobbies())); } }
しかし、ここで問題があることであるオブジェクトのクローン()メソッドがで取得する新しいメソッドとコンストラクタでまだありました!私はそれを理解していませんでしたか?
例深いクローン -
プロトタイプモンキーモンキーカテゴリを作成します。
パッケージcom.pansoft.com.prototype.deep。 輸入java.util.Date; パブリック クラスモンキー{ 公共の int型の高さ。 公共 int型の重量; 公共の日誕生日。 }
それは3つの属性、高さ、幅及び誕生日を持っています。
参照オブジェクト黄金棍棒JinGuBangカテゴリを作成します。
パッケージcom.pansoft.com.prototype.deep。 インポートしたjava.io.Serializable; パブリック クラス JinGuBangが実装シリアライズ{ 公共 フロート H = 100 。 公共 フロート D = 10 ; 公共 のボイド{)(ビッグ 本 .D * = 2 ; この .H * = 2 ; } 公共 ボイド)(小{ この .D / = 2 。 この .H / = 2 。 } }
これは直列化インタフェースは、2つの変数を定義継承と初期化はまた、2つの方法、大きい方、小さい方を定義します。
特定のオブジェクト猿王QiTianDaShengカテゴリを作成します。
パッケージcom.pansoft.com.prototype.deep。 輸入java.io.ByteArrayInputStream。 輸入java.io.ByteArrayOutputStreamを。 輸入java.io.ObjectInputStream。 輸入java.io.ObjectOutputStreamの。 インポートしたjava.io.Serializable; 輸入java.util.Date; パブリック クラス QiTianDaShengは延び猿実装Cloneableを、シリアライズ{ 公共JinGuBang jinGuBangと、 公共QiTianDaSheng(){ // 只是初始化 この .birthday = 新しい日付(); この.jinGuBang = 新しいJinGuBang()。 } @Override 保護された)オブジェクトのクローンを(スローCloneNotSupportedException { 戻り 、この)(.deepCloneします。 } パブリックオブジェクトdeepClone(){ 試み{ ByteArrayOutputStream BOS = 新しいByteArrayOutputStream(); ObjectOutputStreamのOOS = 新しいObjectOutputStreamの(BOS); oos.writeObject(この); するByteArrayInputStreamビス = 新しいれるByteArrayInputStream(bos.toByteArray())。 ObjectInputStreamのOIS target.height。= 新しいObjectInputStreamの(ビス)。 QiTianDaShengコピー = (QiTianDaSheng)ois.readObject(); copy.birthday = 新しい日付(); 戻り値のコピー。 } キャッチ(例外e){ e.printStackTrace(); リターン ヌル。 } } パブリックQiTianDaSheng shallowColne(QiTianDaSheng対象){ QiTianDaSheng qiTianDaSheng = 新しいQiTianDaSheng()。 qiTianDaSheng.height = qiTianDaSheng.weight = target.weight。 qiTianDaSheng.jinGuBang = target.jinGuBang; qiTianDaSheng.birthday = 新しい新しい日付(); 戻りqiTianDaShengを; } }
これは、clone()メソッドの内部が深いクローンであるクラス及びモンキーCloneableを、直列化インターフェイスを継承をshallowClone(QiTianDaShengターゲット)が浅いクローンです。
これはQiTianDaShengオブジェクトをバイトコードに深い実施例でクローニングすることによって得ました。
テスト:
パッケージcom.pansoft.com.prototype.deep; パブリック クラスDeepCloneTest { 公共の 静的な 無効メイン(文字列[] args)を{ QiTianDaSheng qiTianDaSheng = 新新QiTianDaSheng(); 試み{ QiTianDaShengクローン = (QiTianDaSheng)qiTianDaSheng.clone(); システム。 out.printlnを( "ディープクローン:" +(qiTianDaSheng.jinGuBang == clone.jinGuBang)); } キャッチ(例外e){ e.printStackTrace(); } QiTianDaSheng Q = 新しい新しいQiTianDaSheng()。 QiTianDaSheng N-= Q.shallowColne(Q) のSystem.out.println( "浅いクローン:" +(q.jinGuBang == n.jinGuBang)); } }
発見深いクローン化された2つのオブジェクトが等しい、等しく浅いクローンではありません。クローン化された減価償却費は、ターゲットオブジェクトがシングルトンオブジェクトであることを意味している場合、その深いクローンは、単一のケースを破壊する、そしてどのように深いクローンそれへの損傷の単一のケースを防ぐには?
;すなわちインスタンスを返す - シングルトンクラスがCloneableインタフェースを実装していない、または同一の部分を維持するために、メソッドオーバーライドクローンのいずれかで、クローンプロセスにシングルトンオブジェクトを返します
私たちは、Cloneableインタフェースを実現するためのArrayListを使用しました!