ディープクローンは、2つの方法で実装します:
1)の浅いクローンに基づくによって-implemented方法カバレッジクローンオブジェクトクラス()。
むしろ純粋に参照コピーよりも、真のコピーに目的を達成するために。私たちは、アドレスのクラスを複製する必要があり、cloneメソッドの変更、完全なコードは次のとおりです。
1つのパッケージABC。 2つの 3クラスアドレスはCloneableを実装{ 4プライベート文字列を追加します。 5 6パブリックストリングgetAdd(){ 7戻り加えます。 8} 9 10公共ボイドsetAdd(文字列追加){ 11 this.add =加えます。 12} 13 14 @Override 15パブリックオブジェクトクローン(){ =ヌル16アドレスaddr。 17試み{ 18 ADDR =(アドレス)super.clone(); 19}キャッチ(CloneNotSupportedException電子){ 20 e.printStackTrace(); 21} 22リターンADDR。 23} 47 @Override 24} 25 26クラスの学生は、Cloneableを実装して、{ 27プライベートint型の数を、 28 29プライベートアドレスaddr; 30 31パブリックアドレスgetAddr(){ 32リターンADDR。 33} 34 35公共ボイドsetAddr(アドレスADDR){ 36 this.addr = addrが。 37} 38 39公共のintはgetNumber(){ 40リターン番号。 41} 42 43公共ボイドsetNumber(INT番号){ 44 this.number =番号。 45} 46 48パブリックオブジェクトクローン(){ =ヌル49学生STU。 50試み{ 51 STU =(学生)super.clone(); //浅复制 52}キャッチ(CloneNotSupportedException電子){ 53 e.printStackTrace(); 54} 55 stu.addr =(アドレス)addr.clone(); //深度复制 56リターンSTU。 57} 58} 59パブリッククラスTest { 60 61公共の静的な無効メイン(文字列引数[]){ 62 63アドレスaddr =新しいアドレス()。 64 addr.setAdd( "杭州市")。 65学生STU1 =新しい学生(); 66 stu1.setNumber(123)。 67 stu1.setAddr(ADDR)。 68 69学生STU2 =(学生)stu1.clone(); 70 71のSystem.out.printlnである( "学生1:" + stu1.getNumber()+ " )アドレス:." + Stu1.getAddr(getAdd()); 72のSystem.out.println( "学生2:" + stu2.getNumber()+ "アドレス:" + stu2.getAddr()getAdd());. 73である 74 addr.setAdd( "ウェストレイクディストリ"); 75 76のSystem.out.println( "学生1:" + STU1 .getNumber()+ "アドレス:" + stu1.getAddr()getAdd());. 77のSystem.out.println( "学生2:" + stu2.getNumber()+ " アドレス:" + stu2.getAddr ().getAdd()); 78} 79}
結果:
学生1:123、住所:杭州 学生2:123、住所:杭州 学生1:123、住所:西湖地区 学生2:123、住所:杭州
2) (直列化)方法(クローン多層の配列によって)問題を解決します。
また、内側の参照型は、別の型への参照が含まれたタイプまたはクラスの多くの参照が含まれている参照型場合、クローンを用いた方法は、非常に面倒であろう。その後、我々は深いクローニング目的を達成するために、シリアル化のアプローチを使用することができます。
ストリームオブジェクトは、元のオブジェクトのコピーであり、元のオブジェクトがまだメモリ内に存在するシリアライゼーションは、書かれたオブジェクトの処理フローです。シリアル化は、それ自体をコピーすることができる唯一のオブジェクトをコピーすることによって達成され、そのメンバオブジェクトの参照は、加工対象物ストリームのシーケンスにより書き込まれ、コピーされ、そこから流れが深いクローンを達成することができる読み出すことができます。そのシリアライズされたオブジェクトのクラスがSerializableインタフェースを実装しなければならない、またはシリアル化操作を実現することはできません達成することに注意してください。
コードシリアライズCloneableインタフェースおよびインタフェースのJava言語は非常に単純なを提供し、彼らは空のインターフェースです。このインターフェースはまた、インタフェースは、任意のメソッドを定義していない特定し、空のマーカーインターフェイスとして知られ、その役割は、これらのインタフェースかどうかをJREの実装クラスを伝えることです、クローニング、配列などのサポートをサポートするかどうかのような機能を有します
外側実装シリアライズクラスパブリック1 { 2プライベートロングのserialVersionUID =最終静的369285298572941L; 3公共インナーインナー; // Discription 4:[ディープコピー方法を必要とする対象、及び全てのオブジェクトは、直列化されたオブジェクトのプロパティを達成している] 。5外公共myclone() { 6アウターアウター= NULL;。 。7トライ{
// 将该对象序列化成流,因为写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。所以利用这个特性可以实现对象的深拷贝
8 ByteArrayOutputStream新しい新しいByteArrayOutputStream BAOS =();。 。9にObjectOutputStreamたObjectOutputStream OOS新しい新=(BAOS); 10 oos.writeObject(この) 。ターゲットに//ストリーム・シーケンス11 12れるByteArrayInputStream BAIS =新しいですれるByteArrayInputStream(baos.toByteArray()); 図13は、ObjectInputStreamの新しい新OIS = ObjectInputStreamの(BAIS)である; 14 =外部(外側)ois.readObject(); 15}キャッチ(IOExceptionを電子){ 16 e.printStackTrace(); 17}キャッチ(ClassNotFoundExceptionが電子){ 18 e.printStackTrace(); 19} 20リターンアウター。 21} 22}
1つのパブリッククラスがインナーシリアライズを実装{ 2プライベート静的最終長いのserialVersionUID = 872390113109L。 3公共の文字列名=「」; 4 5公共の内側(文字列名){ 6 this.name =名。 7} 8 9 @Override 10パブリック文字列のtoString(){ 11リターン"内部的名值为:" +名。 12} 13}
これはまた、独立して互いの値の、メモリ空間内の2つの完全に独立したオブジェクトの存在を可能にします。
概要
オブジェクトのクローニングを達成するための2つの方法があります。
1)Cloneableインタフェースを実現するクラスオブジェクトのクローン()メソッドをオーバーライドします。
2)オブジェクトのシリアライゼーションおよびデシリアライゼーションをクローニングすることによって達成Serializableを実装し、クローンの実際の深さを達成することができます。
注意を払います クローニングのだけでなく、深さを達成するためにシリアライズとデシリアライズをクローニングに基づいて、より重要なのは、ジェネリック医薬品によって制限されている、あなたは、オブジェクトが直列化をサポートしてクローンを作成する場合は、このチェックがない実行時に、完全なコンパイラでチェックアウトすることができます例外をスロー、この方式は、クローンクローンオブジェクトクラスを使用する方法よりもはるかに優れています。常により良いさらさコンパイル時の問題は、実行時に問題を残してみましょう。 |