การโคลนนิ่งฉันเชื่อว่าทุกคนเคยได้ยินเรื่องนี้ แกะโคลนตัวแรกของโลก Dolly ใช้เทคโนโลยีการปลูกถ่ายนิวเคลียร์เพื่อปลูกฝังบุคคลใหม่ในเซลล์ร่างกายที่เป็นผู้ใหญ่ของสัตว์เลี้ยงลูกด้วยนมซึ่งมีมนต์ขลังมาก ในความเป็นจริงยังมีแนวคิดของการโคลนนิ่งใน Java นั่นคือการตระหนักถึงการคัดลอกวัตถุ
บทความนี้จะพยายามแนะนำคำถามเชิงลึกเกี่ยวกับการโคลนนิ่งใน Java โดยหวังว่าจะช่วยให้คุณเข้าใจการโคลนนิ่งได้ดีขึ้น
สมมติว่าคุณต้องการคัดลอกตัวแปรอย่างง่าย ง่ายมาก:
int แอปเปิ้ล = 5; ไข่มุก int = แอปเปิ้ล;
ไม่เพียง แต่ประเภท int ประเภทข้อมูลดั้งเดิมอีกเจ็ดชนิด (บูลีน, ถ่าน, ไบต์, สั้น, ลอย, double.long) ยังใช้กับสถานการณ์ประเภทนี้
แต่ถ้าคุณคัดลอกวัตถุสถานการณ์จะซับซ้อนเล็กน้อย
สมมติว่าฉันเป็นผู้เริ่มต้นฉันจะเขียนสิ่งนี้:
นักเรียนชั้นเรียน {หมายเลข int ส่วนตัว; สาธารณะ int getNumber () {หมายเลขคืน; } โมฆะสาธารณะ setNumber (หมายเลข int) {this.number = number; }} การทดสอบระดับสาธารณะ {โมฆะคงที่สาธารณะหลัก (String args []) {นักเรียน stu1 = นักเรียนใหม่ (); stu1.setNumber (12345); นักเรียน stu2 = stu1; System.out.println ("นักเรียน 1:" + stu1.getNumber ()); System.out.println ("นักเรียน 2:" + stu2.getNumber ()); -ผลลัพธ์:
นักเรียน 1: 12345
นักเรียน 2: 12345
ที่นี่เราได้ปรับแต่งชั้นเรียนนักเรียนซึ่งมีเพียงหนึ่งสาขา
เราสร้างอินสแตนซ์ของนักเรียนใหม่และกำหนดค่าให้กับอินสแตนซ์ STU2 (นักเรียน stu2 = stu1;)
มาดูผลการพิมพ์ เป็นสามเณรฉันตบหน้าอกและหน้าท้อง แต่วัตถุถูกคัดลอกเช่นนี้
นี่เป็นกรณีจริงเหรอ?
เราพยายามเปลี่ยนฟิลด์ตัวเลขของอินสแตนซ์ STU2 จากนั้นพิมพ์ผลลัพธ์และดู:
stu2.setNumber (54321); System.out.println ("นักเรียน 1:" + stu1.getNumber ()); System.out.println ("นักเรียน 2:" + stu2.getNumber ());ผลลัพธ์:
นักเรียน 1: 54321
นักเรียน 2: 54321
นี่เป็นเรื่องแปลก เหตุใดนักเรียนจำนวนนักเรียน 2 จึงเปลี่ยนไปและจำนวนนักเรียนของนักเรียน 1 ก็เปลี่ยนไปเช่นกัน
เหตุผลอยู่ในประโยค (stu2 = stu1) จุดประสงค์ของคำสั่งนี้คือการกำหนดการอ้างอิงของ STU1 ถึง STU2
ด้วยวิธีนี้ STU1 และ STU2 ชี้ไปที่วัตถุเดียวกันในหน่วยหน่วยความจำ ดังที่แสดงในภาพ:
ดังนั้นเราจะคัดลอกวัตถุได้อย่างไร?
คุณจำวัตถุกษัตริย์ทุกวัยได้หรือไม่? มันมี 11 วิธีและมีสองวิธีที่ได้รับการป้องกันซึ่งหนึ่งในนั้นคือวิธีการโคลน
ใน Java คลาสทั้งหมดได้รับการสืบทอดมาจากคลาสวัตถุในแพ็คเกจภาษา Java โดยค่าเริ่มต้น ตรวจสอบซอร์สโค้ด คุณสามารถคัดลอก SRC.ZIP ในไดเรกทอรี JDK ของคุณไปยังสถานที่อื่นและคลายการบีบอัดและซอร์สโค้ดทั้งหมดรวมอยู่ด้วย ฉันพบว่ามีวิธีการที่มีการป้องกันการเข้าถึงโคลน ()::
/*สร้างและส่งคืนสำเนาของวัตถุนี้ ความหมายที่แม่นยำของ "คัดลอก" อาจขึ้นอยู่กับคลาสของวัตถุความตั้งใจทั่วไปคือสำหรับวัตถุใด ๆ x, นิพจน์: 1) x.clone ()! = x จะเป็นจริง 2) x.clone (). getClass () == x.getClass () โยน ClonenotsupportedException;
หากคุณมองอย่างใกล้ชิดมันยังคงเป็นวิธีการดั้งเดิม ทุกคนรู้ว่าวิธีการดั้งเดิมนั้นใช้รหัสในภาษาที่ไม่ใช่ภาษาชวาและใช้สำหรับโปรแกรมการโทรโดยโปรแกรม Java เนื่องจากโปรแกรม Java ทำงานบนเครื่องเสมือน JVM จึงไม่มีวิธีในการเข้าถึงโปรแกรมที่เกี่ยวข้องกับระบบปฏิบัติการพื้นฐานและพวกเขาสามารถนำไปใช้กับภาษาที่อยู่ใกล้กับระบบปฏิบัติการเท่านั้น
การประกาศครั้งแรกทำให้มั่นใจได้ว่าวัตถุโคลนจะมีการจัดสรรที่อยู่หน่วยความจำแยกต่างหาก
การประกาศครั้งที่สองแสดงให้เห็นว่าวัตถุต้นฉบับและโคลนควรมีประเภทคลาสเดียวกัน แต่ไม่จำเป็น
คำแถลงที่สามแสดงให้เห็นว่าวัตถุต้นฉบับและโคลนควรถูกใช้อย่างเท่าเทียมกันโดยวิธี Equals () แต่มันไม่ได้บังคับ
เนื่องจากคลาสแม่ของแต่ละคลาสเป็นวัตถุพวกเขาทั้งหมดจึงมีวิธีการโคลน () แต่เนื่องจากวิธีการได้รับการปกป้องจึงไม่สามารถเข้าถึงได้นอกชั้นเรียน
ในการคัดลอกวัตถุคุณต้องแทนที่วิธีการโคลน
ทำไมต้องโคลน?
ลองนึกถึงคำถามก่อนทำไมคุณต้องโคลนวัตถุ มันไม่เป็นไรที่จะเป็นวัตถุใหม่หรือไม่?
คำตอบคือ: วัตถุโคลนอาจมีคุณสมบัติที่แก้ไขบางอย่างและคุณสมบัติของวัตถุใหม่ยังคงเป็นค่าในเวลาที่เริ่มต้นดังนั้นเมื่อจำเป็นต้องใช้วัตถุใหม่เพื่อบันทึก "สถานะ" ของวัตถุปัจจุบันวิธีการโคลนขึ้นอยู่กับวิธีการโคลน ดังนั้นฉันไม่เป็นไรที่จะกำหนดคุณสมบัติชั่วคราวของวัตถุนี้ให้กับวัตถุใหม่ของฉันทีละตัว? ไม่เป็นไร แต่อย่าพูดถึงเรื่องนี้ก่อน ประการที่สองผ่านซอร์สโค้ดข้างต้นทุกคนค้นพบว่าโคลนเป็นวิธีการดั้งเดิมซึ่งรวดเร็วและนำไปใช้ที่ด้านล่าง
ให้ฉันเตือนคุณว่าวัตถุทั่วไปของเรา A = New Object (); Object B; B = A; รูปแบบของการอ้างอิงรหัสนี้คือที่อยู่ของวัตถุในหน่วยความจำและวัตถุ A และ B ยังคงชี้ไปที่วัตถุเดียวกัน
วัตถุที่ได้รับมอบหมายผ่านวิธีการโคลนนั้นมีอยู่โดยไม่ขึ้นกับวัตถุต้นฉบับ
วิธีใช้การโคลนนิ่ง
ก่อนอื่นให้ฉันแนะนำวิธีการโคลนนิ่งที่แตกต่างกันสองวิธีคือการโคลนนิ่งตื้นและการโคลนนิ่งลึก
ในภาษา Java ประเภทข้อมูลจะแบ่งออกเป็นประเภทค่า (ประเภทข้อมูลพื้นฐาน) และประเภทอ้างอิง ประเภทของค่ารวมถึงประเภทข้อมูลอย่างง่ายเช่น int, double, byte, boolean, char, ฯลฯ และประเภทการอ้างอิงรวมถึงประเภทที่ซับซ้อนเช่นคลาสอินเตอร์เฟสอาร์เรย์ ฯลฯ ความแตกต่างที่สำคัญระหว่างการโคลนตื้นและการโคลนลึกคือการรองรับการคัดลอกตัวแปรสมาชิกประเภทอ้างอิงหรือไม่ ทั้งสองจะได้รับการแนะนำในรายละเอียดด้านล่าง
ขั้นตอนทั่วไปคือ (การโคลนนิ่งตื้น):
1. คลาสที่คัดลอกจะต้องใช้อินเทอร์เฟซ clonenable (หากคุณไม่ได้ใช้งาน clonenotsupportedException จะถูกโยนลงเมื่อเรียกวิธีการโคลน) อินเทอร์เฟซนี้เป็นอินเตอร์เฟสแท็ก (ไม่มีวิธีใด ๆ )
2. แทนที่วิธีการโคลน () และตั้งค่าตัวปรับเปลี่ยนการเข้าถึงเป็นสาธารณะ เรียกเมธอด super.clone () ในวิธีการเพื่อรับวัตถุคัดลอกที่ต้องการ (ดั้งเดิมเป็นวิธีการในท้องถิ่น)
ต่อไปนี้คือการปรับเปลี่ยนวิธีการข้างต้น:
นักเรียนชั้นเรียนใช้ cloneable {หมายเลข int ส่วนตัว; int public int getNumber () {หมายเลขคืน;} โมฆะสาธารณะ setNumber (หมายเลข int) {this.number = number;}@override Override Object Clone () {นักเรียน stu = null; ลอง {stu = (นักเรียน) super.clone () stu;}} การทดสอบระดับสาธารณะ {โมฆะคงที่สาธารณะหลัก (สตริง args []) {นักเรียน stu1 = นักเรียนใหม่ (); stu1.setNumber (12345); นักเรียน stu2 = (นักเรียน) stu1.clone (); stu2.getNumber ()); stu2.setNumber (54321); System.out.println ("นักเรียน 1:" + stu1.getNumber ()); System.out.println ("Student2:" + stu2.getNumber ());}}}}}ผลลัพธ์:
นักเรียน 1: 12345
นักเรียน 2: 12345
นักเรียน 1: 12345
นักเรียน 2: 54321
หากคุณไม่เชื่อว่าวัตถุทั้งสองนี้ไม่ใช่วัตถุเดียวกันคุณสามารถดูประโยคนี้ได้:
System.out.println (stu1 == stu2); // เท็จ
สำเนาข้างต้นเรียกว่าการโคลนนิ่งตื้น
นอกจากนี้ยังมีสำเนาลึกที่ซับซ้อนกว่าเล็กน้อย:
มาเพิ่มชั้นเรียนที่อยู่ในชั้นเรียนนักเรียนกันเถอะ
ที่อยู่คลาส {สตริงส่วนตัวเพิ่ม; สตริงสาธารณะ getAdd () {return add;} โมฆะสาธารณะ setAdd (เพิ่มสตริง) {this.add = add;}} คลาสนักเรียนใช้ cloneable {หมายเลข int ส่วนตัว; ที่อยู่ส่วนตัว addr; ที่อยู่สาธารณะ getaddr () {return addr; setNumber (หมายเลข int) {this.number = number;}@override object clone () {นักเรียน stu = null; ลอง {stu = (นักเรียน) super.clone ();} catch (clonenotsupportedException e) {e.printstacktrace () ที่อยู่ (); addr.setAdd ("เมืองหางโจว"); นักเรียน stu1 = นักเรียนใหม่ (); stu1.setnumber (123); stu1.setaddr (addr); นักเรียน stu2 = (นักเรียน) stu1.clone (); stu1.getaddr (). getAdd ()); system.out.println ("นักเรียน 2:" + stu2.getNumber () + ", เพิ่ม:" + stu2.getAddr (). getAdd ());}}}ผลลัพธ์:
นักเรียน 1: 123, ที่อยู่: Hangzhou Student 2: 123, ที่อยู่: หางโจว
เมื่อมองแวบแรกไม่มีปัญหานี่เป็นกรณีนี้หรือไม่?
เราพยายามเปลี่ยนที่อยู่ของอินสแตนซ์ AddR ในวิธีหลัก
addr.setAdd ("เขต xihu"); System.out.println ("นักเรียน 1:" + stu1.getNumber () + ", เพิ่ม:" + stu1.getaddr (). getAdd ()); System.out.println ("นักเรียน 2:" + stu2.getNumber () + ", เพิ่ม:" + stu2.getAddr (). getAdd ());ผลลัพธ์:
นักเรียน 1: 123, ที่อยู่: Hangzhou Student 2: 123, ที่อยู่: Hangzhou Student 1: 123, ที่อยู่: Xihu District Student 2: 123, ที่อยู่: Xihu District
นี่เป็นเรื่องแปลกทำไมที่อยู่ของนักเรียนทั้งสองถึงเปลี่ยนไป?
เหตุผลก็คือการคัดลอกการอ้างอิงของตัวแปร addr เท่านั้นและไม่เปิดพื้นที่อีกชิ้นหนึ่ง หลังจากคัดลอกค่าแล้วให้ส่งคืนการอ้างอิงไปยังวัตถุใหม่
ดังนั้นเพื่อให้บรรลุวัตถุคัดลอกที่แท้จริงไม่ใช่การคัดลอกอ้างอิงอย่างหมดจด เราจำเป็นต้องคัดลอกคลาสที่อยู่และแก้ไขวิธีการโคลน รหัสที่สมบูรณ์มีดังนี้:
แพ็คเกจ ABC; ที่อยู่ชั้นเรียนใช้ cloneable {สตริงส่วนตัวเพิ่ม; สตริงสาธารณะ getAdd () {return add; } โมฆะสาธารณะ setAdd (เพิ่มสตริง) {this.add = เพิ่ม; } @Override วัตถุสาธารณะโคลน () {ที่อยู่ addr = null; ลอง {addr = (ที่อยู่) super.clone (); } catch (clonenotsupportedException e) {e.printStackTrace (); } return addr; }} ชั้นเรียนนักเรียนใช้ cloneable {หมายเลข int ส่วนตัว; ที่อยู่ส่วนตัว addr; ที่อยู่สาธารณะ getaddr () {return addr; } โมฆะสาธารณะ setaddr (ที่อยู่ addr) {this.addr = addr; } public int getNumber () {หมายเลขส่งคืน; } โมฆะสาธารณะ setNumber (หมายเลข int) {this.number = number; } @Override วัตถุสาธารณะโคลน () {นักเรียน stu = null; ลอง {stu = (นักเรียน) super.clone (); // slotow copy} catch (clonenotsupportedException e) {e.printstacktrace (); } stu.addr = (ที่อยู่) addr.clone (); // สำเนาลึกส่งคืน Stu; }} การทดสอบคลาสสาธารณะ {โมฆะคงที่สาธารณะหลัก (สตริง args []) {ที่อยู่ addr = ที่อยู่ใหม่ (); addr.setAdd ("เมืองหางโจว"); นักเรียน stu1 = นักเรียนใหม่ (); stu1.setNumber (123); stu1.setaddr (addr); นักเรียน stu2 = (นักเรียน) stu1.clone (); System.out.println ("นักเรียน 1:" + stu1.getNumber () + ", ที่อยู่:" + stu1.getAddr (). getAdd ()); System.out.println ("นักเรียน 2:" + stu2.getNumber () + ", ที่อยู่:" + stu2.getAddr (). getAdd ()); addr.setAdd ("เขต xihu"); System.out.println ("นักเรียน 1:" + stu1.getNumber () + ", ที่อยู่:" + stu1.getAddr (). getAdd ()); addr.setAdd ()); System.out.println ("นักเรียน 2:" + stu2.getNumber () + ", ที่อยู่:" + stu2.getAddr (). getAdd ()); -ผลลัพธ์:
นักเรียน 1: 123, ที่อยู่: Hangzhou Student 2: 123, ที่อยู่: Hangzhou Student 1: 123, ที่อยู่: Xihu District Student 2: 123, ที่อยู่: Hangzhou City
ผลลัพธ์นี้สอดคล้องกับความคิดของเรา
ในที่สุดเราสามารถดูหนึ่งในคลาสใน API ที่ใช้วิธีการโคลน:
java.util.date:
/*** ส่งคืนสำเนาของวัตถุนี้ */ วัตถุสาธารณะโคลน () {วันที่ d = null; ลอง {d = (วันที่) super.clone (); if (cdate! = null) {d.cdate = (basecalendar.date) cdate.clone (); }} catch (clonenotsupportedException e) {} // จะไม่เกิดขึ้นส่งคืน d; -หมวดหมู่นี้เป็นสำเนาที่ลึกล้ำ
การโคลนตื้นและการโคลนนิ่งลึก
1. การโคลนนิ่งตื้น
ในการโคลนนิ่งตื้นหากตัวแปรสมาชิกของวัตถุต้นแบบเป็นประเภทค่าใด ๆ สำเนาหนึ่งจะถูกคัดลอกไปยังวัตถุโคลน หากตัวแปรสมาชิกของวัตถุต้นแบบเป็นประเภทอ้างอิงที่อยู่ของวัตถุอ้างอิงจะถูกคัดลอกไปยังวัตถุที่โคลนนั่นคือตัวแปรสมาชิกของวัตถุต้นแบบและวัตถุโคลนชี้ไปที่ที่อยู่หน่วยความจำเดียวกัน
พูดง่ายๆในการโคลนนิ่งตื้นเมื่อวัตถุถูกคัดลอกเฉพาะตัวแปรสมาชิกของประเภทค่าของวัตถุจะถูกคัดลอกและวัตถุสมาชิกของประเภทอ้างอิงไม่ได้คัดลอก
ในภาษา Java การโคลนนิ่งตื้นสามารถนำไปใช้โดยการเขียนทับวิธีการโคลน () ของคลาสวัตถุ
2. การโคลนนิ่งลึก
ในการโคลนนิ่งลึกไม่ว่าตัวแปรสมาชิกของวัตถุต้นแบบจะเป็นประเภทค่าหรือประเภทอ้างอิงหนึ่งสำเนาจะถูกคัดลอกไปยังวัตถุโคลน การโคลนนิ่งลึกยังคัดลอกวัตถุที่อ้างอิงทั้งหมดของวัตถุต้นแบบไปยังวัตถุโคลน
พูดง่ายๆในการโคลนนิ่งลึกยกเว้นวัตถุที่ถูกคัดลอกตัวแปรสมาชิกทั้งหมดที่อยู่ในวัตถุจะถูกคัดลอกด้วย
ในภาษา Java หากคุณต้องการใช้การโคลนนิ่งลึกสามารถนำไปใช้ได้โดยการเขียนทับวิธีการ clone () ของคลาสวัตถุหรือสามารถนำไปใช้โดยการทำให้เป็นอนุกรม ฯลฯ ฯลฯ
(หากประเภทการอ้างอิงมีหลายประเภทอ้างอิงหรือคลาสประเภทอ้างอิงภายในมีประเภทอ้างอิงมันจะลำบากมากในการใช้วิธีการโคลนในเวลานี้เราสามารถใช้การทำให้เป็นอนุกรมเพื่อใช้การโคลนลึกของวัตถุ)
การทำให้เป็นอนุกรมเป็นกระบวนการเขียนวัตถุไปยังสตรีม วัตถุที่เขียนไปยังสตรีมเป็นสำเนาของวัตถุต้นฉบับและวัตถุต้นฉบับยังคงอยู่ในหน่วยความจำ สำเนาที่ใช้งานโดยการทำให้เป็นอนุกรมไม่เพียง แต่คัดลอกวัตถุเท่านั้น แต่ยังคัดลอกวัตถุสมาชิกที่อ้างอิง ดังนั้นโดยการทำให้เป็นอนุกรมวัตถุไปยังสตรีมแล้วอ่านออกจากลำธารการโคลนนิ่งลึกสามารถทำได้ ควรสังเกตว่าคลาสของวัตถุที่สามารถใช้งานอนุกรมจะต้องใช้อินเทอร์เฟซแบบอนุกรมมิฉะนั้นการดำเนินการอนุกรมไม่สามารถนำไปใช้ได้
ซึ่งขยายออกไป
รหัสของอินเทอร์เฟซ cloneable และอินเตอร์เฟส serializable ที่จัดทำโดยภาษา Java นั้นง่ายมาก พวกเขาเป็นทั้งอินเทอร์เฟซที่ว่างเปล่า อินเทอร์เฟซที่ว่างเปล่านี้เรียกว่าอินเทอร์เฟซการระบุตัวตน ไม่มีคำจำกัดความของวิธีการใด ๆ ในอินเทอร์เฟซการระบุตัวตน ฟังก์ชั่นของมันคือการบอก JRE ว่าคลาสการใช้งานของอินเทอร์เฟซเหล่านี้มีฟังก์ชั่นบางอย่างหรือไม่เช่นว่าพวกเขาสนับสนุนการโคลนนิ่งไม่ว่าจะสนับสนุนการทำให้เป็นอนุกรม ฯลฯ ฯลฯ
แก้ปัญหาการโคลนนิ่งหลายชั้น
หากประเภทการอ้างอิงมีประเภทอ้างอิงหลายประเภทหรือคลาสประเภทอ้างอิงภายในมีประเภทอ้างอิงมันจะลำบากมากในการใช้วิธีการโคลน ในเวลานี้เราสามารถใช้การทำให้เป็นอนุกรมเพื่อใช้การโคลนนิ่งลึกของวัตถุ
ชั้นเรียนสาธารณะ Outer ใช้งาน serializable {ส่วนตัวคงที่สุดท้าย Long SerialVersionUID = 369285298572941L; // เป็นการดีที่สุดที่จะประกาศภายใน ID สาธารณะภายในอย่างชัดเจน // discription: [วิธีการคัดลอกลึกต้องการวัตถุและคุณสมบัติของวัตถุทั้งหมดที่จะทำให้เป็นอนุกรม] myclone ด้านนอกสาธารณะ () {Outer Outer = null; ลอง {// serialize วัตถุลงในสตรีมเพราะสิ่งที่เขียนในสตรีมเป็นสำเนาของวัตถุและวัตถุต้นฉบับยังคงมีอยู่ใน JVM ดังนั้นการใช้คุณสมบัตินี้คุณสามารถทำสำเนาลึกของวัตถุ ByteArrayOutputStream BAOS = ใหม่ byteArrayOutputStream (); ObjectOutputStream OOS = ใหม่ ObjectOutputStream (BAOS); oos.writeObject (นี่); // serialize สตรีมลงในวัตถุ ByteArrayInputStream bais = ใหม่ bytearrayInputStream (baos.tobytearray ()); ObjectInputStream OIS = ใหม่ ObjectInputStream (BAIS); ด้านนอก = (ด้านนอก) ois.readObject (); } catch (ioexception e) {e.printstacktrace (); } catch (classnotFoundException e) {e.printStackTrace (); } return Outer; -ภายในจะต้องใช้ serializable มิฉะนั้นจะไม่สามารถต่อเนื่องได้:
ชั้นเรียนสาธารณะใช้การใช้งาน serializable {private static final final long long serialversionuid = 872390113109L; // เป็นการดีที่สุดที่จะประกาศชื่อสตริงสาธารณะ ID อย่างชัดเจน = ""; Public Inner (ชื่อสตริง) {this.name = name; } @Override สตริงสาธารณะ toString () {return "ค่าชื่อของภายในคือ:" + ชื่อ; -นอกจากนี้ยังสามารถเปิดใช้งานวัตถุทั้งสองที่มีอยู่อย่างสมบูรณ์ในพื้นที่หน่วยความจำโดยไม่ส่งผลกระทบต่อค่าของกันและกัน
สรุป
มีสองวิธีในการใช้การโคลนนิ่งวัตถุ:
1). ใช้อินเทอร์เฟซ cloneable และแทนที่เมธอด clone () ในคลาสวัตถุ
2). ใช้อินเทอร์เฟซแบบอนุกรมและใช้การโคลนผ่านการทำให้เป็นอนุกรมของวัตถุและ deserialization ซึ่งสามารถตระหนักถึงการโคลนลึกที่แท้จริง
หมายเหตุ: การโคลนนิ่งขึ้นอยู่กับการทำให้เป็นอนุกรมและ deserialization ไม่ได้เป็นเพียงการโคลนนิ่งลึก แต่ที่สำคัญกว่านั้นคือผ่านข้อ จำกัด ทั่วไปสามารถตรวจสอบได้ว่าวัตถุที่ถูกโคลนรองรับการทำให้เป็นอนุกรมหรือไม่ การตรวจสอบนี้ทำโดยคอมไพเลอร์และไม่ได้ทำข้อยกเว้นที่รันไทม์ โซลูชันนี้เห็นได้ชัดว่าดีกว่าการโคลนนิ่งวัตถุโดยใช้วิธีการโคลนของคลาสวัตถุ เป็นการดีกว่าเสมอที่จะปล่อยให้ปัญหาอยู่ที่รันไทม์โดยการเปิดเผยเมื่อรวบรวม
ข้างต้นเป็นคำอธิบายรายละเอียดทั้งหมดของรหัสการใช้งานการเขียนโปรแกรมการเขียนโปรแกรม Java (COPY) ฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน เพื่อนที่สนใจสามารถอ้างถึงหัวข้ออื่น ๆ ที่เกี่ยวข้องในเว็บไซต์นี้ต่อไป หากมีข้อบกพร่องใด ๆ โปรดฝากข้อความไว้เพื่อชี้ให้เห็น