Java จัดเตรียมกลไกที่เรียกว่า serialization
ดังนั้นหากเราได้สร้างวัตถุให้กับวัตถุมันสามารถอ่านและปิดการใช้งานผ่านประเภทของวัตถุและข้อมูลอื่น ๆ และในที่สุดก็ได้รับต้นแบบของวัตถุ
ObjectInputStream และ ObjectOutputStream Objects เป็นวัตถุสตรีมมิ่งระดับสูงรวมถึงวิธีการทำให้เป็นอนุกรมและด้านหลัง
ObjectOutputStream มีวิธีการมากมายสำหรับวัตถุที่เป็นอนุกรม
Void Private WriteObject (ObjectOutputStream OS) พ่น IOException {}
ObjectInputStream ที่คล้ายกันมีวิธีการต่อไปนี้:
Private Void Brand (ObjectInputStream) พ่น IOException, classnotFoundException {}
แล้วมันจะต้องเป็นอนุกรมที่ไหน? การทำให้เป็นอนุกรมมักใช้ข้อมูลการส่งเครือข่ายหรือบันทึกวัตถุไปยังไฟล์ ข้อมูลที่กล่าวถึงที่นี่เป็นวัตถุและไม่ใช่ข้อความ
ปัญหาในขณะนี้คือสถาปัตยกรรมเครือข่ายและฮาร์ดดิสก์ของเราสามารถระบุไบนารีและไบต์เท่านั้นและไม่สามารถจดจำวัตถุ Java ได้
序列化就是把Java对象中的value/states翻译为字节,以便通过网络传输或者保存。另外,反序列化就是通过读取字节码,并把它翻译回java对象。
serialVersionUID概念
serialVersionUID 是用于保证同一个对象(在序列化中会被用到)可以在Deserialization过程中被载入。serialVersionUID 是用于对象的版本控制。你可以参考serialVersionUID in java serialization获取更多信息。
对于序列化:
ขั้นตอนมีดังนี้:
มาดูรายการ:
สร้างพนักงาน. java ใน src-> org.arpit.javapostsforning
1.Mployee.java
แพ็คเกจ org.arpit.javapostsforning; = EmployeeId;} Public String getEmployeEname () {return Employeeename;} โมฆะสาธารณะ setemployeename (String EmployeEname) {this.employeena me = experename;} สตริงสาธารณะ getDeppartment () {แผนกส่งคืน; Depapartment = แผนก;}}
อย่างที่คุณเห็นหากคุณต้องการทำให้คลาสใด ๆ คุณต้องใช้อินเทอร์เฟซแบบ serializable
อินเทอร์เฟซเครื่องหมายใน Java เป็นอินเทอร์เฟซที่ไม่มีฟิลด์หรือวิธีการใด ๆ
2.SerializeMain.java
แพ็คเกจ org.arpit.javapostsforning; ] args) {พนักงาน EMP = พนักงานใหม่ (); ser "); ObjectPutStream Outstream = new ObjectPutStream (fileout); Outstream.writeObject (EMP); Outstream.close (); Exception i) {i.printStackTrace ();}}}}
对于反序列化:
ขั้นตอนคือ
ในแพ็คเกจ src-> org.arpit.javapostsforlearning สร้าง deserializeMain.java
3.DeserializeMain.java
แพ็คเกจ org.arpit.javapostsforning; นำเข้า java.io.ioexception; null; ioexception i) {i.printstacktrace (); ... "); System.out.println (" EMP ID: " + emp.getEmployeeId ()); System.out.println (" ชื่อ: " + emp.getemployeename ()); stem.out.println (" แผนก: " + emp.getDeppartment ());}}
4. วิ่ง:
ก่อนอื่นให้เรียกใช้ serializeMain.java จากนั้นเรียกใช้ deserializeMain.java คุณจะได้รับผลลัพธ์ต่อไปนี้:
deserialized emblayee ... emp id: 101name: arpitdepapartment: CS
ด้วยวิธีนี้เราทำให้วัตถุของพนักงานต่อเนื่องและนำไปใช้กับมัน สิ่งนี้ดูง่าย แต่ถ้ามีการอ้างอิงวัตถุและการสืบทอดสถานการณ์จะซับซ้อน ลองมาดูตัวอย่างทีละคนเพื่อดูวิธีการทำให้เป็นอนุกรมในโอกาสต่าง ๆ
กรณีที่ 1 -หากวัตถุเสนอราคาวัตถุอื่น ๆ ฉันควรทำอย่างไร
เราได้เห็นตัวอย่างที่ง่ายที่สุดในตอนนี้เราเห็นวิธีจัดการกับวัตถุอื่น ๆ ในวัตถุ เราจะทำให้เป็นอนุกรมได้อย่างไร? วัตถุที่อ้างถึงจะทำให้เป็นอนุกรมหรือไม่? ใช่คุณไม่จำเป็นต้องได้รับการจัดลำดับอย่างชัดเจน เมื่อคุณทำให้เป็นอนุกรมวัตถุใด ๆ หากมีวัตถุอ้างอิงการทำให้เป็นอนุกรม Java จะทำให้ไดอะแกรมวัตถุทั้งหมดของวัตถุทั้งหมดโดยอัตโนมัติ ตัวอย่างเช่นตอนนี้พนักงานเสนอราคาวัตถุที่อยู่และที่อยู่ยังเสนอราคาวัตถุอื่น ๆ (ตัวอย่างเช่นบ้าน) จากนั้นเมื่อคุณทำให้เป็นอนุกรมวัตถุของพนักงานวัตถุอื่น ๆ ที่อ้างถึงทั้งหมดเช่นที่อยู่และที่อยู่บ้านจะถูกทำให้เป็นอนุกรมโดยอัตโนมัติ มาสร้างคลาสที่อยู่และเพิ่มวัตถุของที่อยู่เป็นข้อมูลอ้างอิงเพื่อเพิ่มลงในคลาสพนักงาน
พนักงาน. java:
แพ็คเกจ org.arpit.javapostsforning; this.employeeId = EmployeeId;} สตริงสาธารณะ getemployeename () {return emperyeeename;} โมฆะสาธารณะ setempoloyeename (String EmployeEname) {this.emplayeename = EmployeeEname;} Public String getDeppartment () {return Department; this.department = แผนก;} ที่อยู่สาธารณะ getAddress () {returb address;} public void setaddress (ที่อยู่) {this.address = ที่อยู่;}}
ในแพ็คเกจ org.arpit.javapostsforlerning สร้าง address.java
address.java:
แพ็คเกจ org.arpit.javapostsforning; .city = city;} public int gethomeno () {return homeno;} โมฆะสาธารณะ sethomeno (int home) {this.homeno = homeno;} public Stringstreet () {street;} public void setstreet (String street) {สิ่งนี้ Street = Street;} Public String GetCity () {Return City;} โมฆะสาธารณะ setCity (String City) {this.city = City;}}
ใน org.arpit.javapostsforlerning สร้าง serializedeserializeMain.java
SerializedeserializeMain.java:
org.arpit.javapostsforning; Mandliya */ Public Static Void Main (String [] args) {พนักงาน EMP = พนักงานใหม่ (); 88, "MG Road", "Pune"); ปิด ();} catch (ioexception i) {i.printstacktrace ();} /deserialize emp = l; (พนักงาน) in.reamobject (); พนักงาน deserialized ... "); System .out.println (" EMP ID: " + emp.getEmployeeId ()); System.out.println (" ชื่อ: " + emp.getemployeename ()); mp.getDepartment () ); ที่อยู่ = emp.getaddress ();
เรียกใช้:
เมื่อคุณเรียกใช้ SerializedeserializeMain.java你会得到这样的结果:
java.io.notserializableException: org.arpit.javapostsforning.address ที่ java.io.objectputtream.writeObject0 (แหล่งที่ไม่รู้จัก) ที่ java.i o.objectputstream.defaultWritefields ที่ java.io.objectputStream.writeordinaryObject (แหล่งที่ไม่รู้จัก) ที่ java.io.oBjectPuttream.writeObject0 (แหล่งที่ไม่รู้จัก) ที่ java.o.ob.ob JectOutputStream.writeObject (แหล่งที่ไม่รู้จัก)
เราจะอธิบายว่ามันผิดที่ไหน ฉันลืมที่จะบอกว่าชั้นเรียนที่อยู่จะต้องเป็นอนุกรม จากนั้นคลาสที่อยู่จะต้องสืบทอดอินเตอร์เฟส serialzable
address.java:
นำเข้า Java.io.serializable; .City = City;} int สาธารณะ int gethomeno () {return homeno;} โมฆะสาธารณะ sethomeno (int homeno) {this.homeno = homeno;} public stringstreet () {) return street;} โมฆะสาธารณะ setstreet (String Street) { .Street = Street;} Public String getCity () {return City;} โมฆะสาธารณะ setCity (String City) {this.city = City;}}}
วิ่งอีกครั้ง:
เมื่อคุณวิ่งอีกครั้ง serializedeserializeMain.java คุณสามารถรับผลลัพธ์ต่อไปนี้ได้
deserialized emblayee ... emp id: 101name: arpitdepartment: cscity: pune
กรณีที่ 2: หากเราไม่สามารถเข้าถึงซอร์สโค้ดของวัตถุอ้างอิง (ตัวอย่างเช่นคุณไม่สามารถเข้าถึงซอร์สโค้ดของคลาสที่อยู่ด้านบน)
หากเราไม่สามารถเข้าถึงคลาสที่อยู่เราจะใช้อินเตอร์เฟส serializable ในคลาสที่อยู่ได้อย่างไร มีวิธีอื่นในการบรรลุเป้าหมายหรือไม่? ใช่คุณสามารถสร้างคลาสอื่นสืบทอดที่อยู่แล้วปล่อยให้มันสืบทอดอินเตอร์เฟส serializable แต่สำหรับสถานการณ์ต่อไปนี้โซลูชันนี้จะล้มเหลว:
หากคลาสอ้างอิงถูกกำหนดเป็นขั้นสุดท้าย
หากคลาสอ้างอิงอ้างอิงวัตถุที่ไม่ได้รับการรักษาอื่น
ดังนั้นเราจะทำให้วัตถุของพนักงานเป็นอนุกรมได้อย่างไร? วิธีแก้ปัญหาคือทำเครื่องหมายการเปลี่ยนแปลง หากคุณไม่จำเป็นต้องทำให้เป็นอนุกรมใด ๆ ให้ทำเครื่องหมายว่าเป็นชั่วคราว
ที่อยู่ชั่วคราว
ในชั้นเรียนของพนักงานหลังจากที่อยู่ถูกทำเครื่องหมายว่าเป็นชั่วคราวให้เรียกใช้โปรแกรม คุณจะได้รับ nullpointerexception เนื่องจากการอ้างอิงที่อยู่จะเป็นโมฆะในระหว่างกระบวนการลึก
กรณีที่ 3 -ถ้าฉันยังต้องบันทึกสถานะของวัตถุอ้างอิงอยู่ (ตัวอย่างเช่นวัตถุที่อยู่)
หากคุณทำเครื่องหมายที่อยู่เป็นชั่วคราวในระหว่างกระบวนการของ DEEPERTINE มันจะส่งคืนผลลัพธ์ที่เป็นโมฆะ แต่ถ้าคุณยังต้องการบันทึกสถานะของตนอยู่คุณจะต้องทำให้วัตถุที่อยู่เป็นอนุกรม Java serialization ให้กลไก
พนักงาน. java:
org.arpit.javapostsforning; ที่อยู่; ;} สตริงสาธารณะ getDepAtment () {return supertion;} โมฆะสาธารณะ setDepartment (แผนกสตริง)} ที่อยู่สาธารณะ getAddress () {ที่อยู่ส่งคืน; OS) พ่น IOException, classnotfoundexception {ลอง {os.defaultwriteobject (); ;}} private void readobject (ObjectInputStream คือ) พ่น IOExCetion FoundException {ลอง {is.defaultreadObject (); .ReadObject ();
อีกสิ่งหนึ่งที่ต้องคำนึงถึง ObjectInputStream อ่านลำดับของข้อมูลจาก ObjectOutputStream
สร้าง address.java
Address.java:
แพ็คเกจ org.arpit.javapostsforning; = ถนน; this.city = city;} public int gethomeno () {return homeno;} โมฆะสาธารณะ sethomeno (int homeno) {this.homeno = public String getStreet () {return street; this.street = street;} public String getCity () {return city;} public void setcity (String City) {this.city = city;}}
สร้าง serializedeserializeMain.java
SerializedeserializeMain.java:
org.arpit.javapostsforning; Mandliya */ Public Static Void Main (String [] args) {พนักงาน EMP = พนักงานใหม่ (); 88, "MG Road", "Pune"); ปิด ();} catch (ioexception i) {i.printstacktrace ();} /deserialize emp = l; (พนักงาน) in.reamobject (); พนักงาน deserialized ... "); System .out.println (" EMP ID: " + emp.getEmployeeId ()); System.out.println (" ชื่อ: " + emp.getemployeename ()); mp.getDepartment () ); ที่อยู่ = emp.getaddress ();
วิ่ง:
เมื่อคุณเรียกใช้ SerializedEserializeMain.java
deserialized emblayee ... emp id: 101name: arpitdepartment: cscity: pune
ตอนนี้เราได้รับสถานะของวัตถุที่อยู่เช่นเดียวกับก่อนที่มันจะเป็นอนุกรม
มรดกในการทำให้เป็นอนุกรม:
ทีนี้มาดูกันว่ามรดกมีผลต่อการทำให้เป็นอนุกรมอย่างไร ไม่ว่าคลาสแม่จะเป็นอนุกรมนี้จะนำไปสู่ตัวอย่างมากมาย หากคลาสหลักไม่เป็นอนุกรมเราจะทำอย่างไรและทำงานอย่างไร ลองมาดูตัวอย่าง
เราจะสร้างบุคคล Java เป็นชั้นเรียนของพนักงาน
กรณีที่ 4: หากคลาสแม่เป็นอนุกรม
หากคลาสหลักสามารถทำให้เป็นอนุกรมคลาสการสืบทอดทั้งหมดจะถูกทำให้เป็นอนุกรม
กรณีที่ 5: จะเกิดอะไรขึ้นถ้าคลาสแม่ไม่ได้เป็นอนุกรม?
หากคลาสแม่ไม่ได้รับการรักษาวิธีการประมวลผลของเราจะแตกต่างกันมาก
หากคลาสแม่ไม่ได้รับการรักษาจะต้องไม่มีฟังก์ชันตัวสร้างพารามิเตอร์
person.java
แพ็คเกจ org.arpit.javapostsforning; super (); this.name = name; ;} โมฆะสาธารณะ setNationality (สัญชาติสตริง) {this.nationality = สัญชาติ;}}
สร้างพนักงาน. java
พนักงาน. java:
แพ็คเกจ org.arpit.javapostsforning; .EmployeeId = EmployeeId; แผนก;} โมฆะสาธารณะ setDeppartment (แผนกสตริง) {this.deppartment = แผนก;}}
สร้าง serializedeserializeMain.java
SerializedeserializeMain.java:
org.arpit.javapostsforning; Mandliya */Public Static Void Main (String [] args) {// serialize พนักงาน EMP = พนักงานใหม่ (101, "Arpit", "Indian"); .println ("EMP ID:" + emp.getemployeId ()); GetDeppartment ()); ); *********** ");) ;; ลอง {fileInputStream filein = new FileInputStream (" EmployeeE.ser ");) in.readObject (); in.close (); filein.close () } catch (ioexception i) {i.printstacktrace (); ("หลังอนุกรม"); "แผนก:" + emp.getDeppartment ());
วิ่ง:
เมื่อคุณเรียกใช้ SerializedEserializeMain.java คุณจะได้รับเอาต์พุตต่อไปนี้ ชื่อที่นี่ได้รับการสืบทอดด้วยตนเองดังนั้นในระหว่างกระบวนการลึกชื่อจะเริ่มต้นเป็นค่าเริ่มต้น
กรณีที่ 6 -หากคลาสหลักได้รับการอนุกรม แต่คุณไม่จำเป็นต้องสืบทอดคลาสเป็นอนุกรม
หากคุณไม่ต้องการสืบทอดคลาสที่จะทำให้เป็นอนุกรมคุณต้องใช้วิธีการเขียน () และ readObject () และจำเป็นต้องโยนความผิดปกติของ NotserializableException
案例7 - 可否序列化静态变量?
ไม่สามารถ. เนื่องจากตัวแปรคงที่เป็นระดับคลาสไม่ใช่ระดับวัตถุ
สรุป: