Serialization
และ
SerialVersionUID
ยังคงเป็นปริศนาสำหรับนักพัฒนา Java จำนวนมากเสมอ ฉันมักจะเห็นคำถามเกี่ยวกับ what is
SerialVersionUID
หรือจะเกิดอะไรขึ้นหากฉันไม่ประกาศ
SerialVersionUID
ใน
Serializable
-class?
นอกเหนือจากความสับสนและไม่ค่อยได้ใช้ อีกเหตุผลหนึ่งสำหรับคำถามนี้ก็คือ Eclipse IDE ไม่มีคำเตือน
SerialVersionUID
ตัวอย่างเช่น: "
คลาส Serializable ลูกค้าไม่ได้ประกาศฟิลด์ SerialVersionUID สุดท้ายแบบคงSerializable
ที่
Customer
ประเภท
SerialVersionUID
long " ในบทความนี้ คุณจะไม่เพียงแต่เรียนรู้พื้นฐานของ Java เท่านั้น
SerialVersionUID
แต่ยังรวมถึงผลกระทบต่อกระบวนการซีเรียลไลซ์และดีซีเรียลไลซ์ด้วย เมื่อคุณประกาศคลาส โดย
Serializable
ใช้อินเทอร์เฟซโทเค็น
java.io.Serializable
รันไทม์ของ Java จะจัดเก็บอินสแตนซ์ของคลาสนั้นไว้บนดิสก์โดยใช้กลไกการทำให้เป็นอนุกรมเริ่มต้น เว้นแต่คุณจะกำหนดค่ากระบวนการให้ใช้
อินเทอร์เฟซภายนอกได้ ในระหว่างการทำให้เป็นอนุกรม รันไทม์ Java จะสร้างหมายเลขเวอร์ชันสำหรับคลาสเพื่อให้สามารถดีซีเรียลไลซ์ได้ในภายหลัง ใน Java หมายเลขเวอร์ชันนี้เรียกว่า
SerialVersionUID
. หากในระหว่างการดีซีเรียลไลเซชันไม่มี
SerialVersionUID
การจับคู่ กระบวนการจะออกโดยมีข้อยกเว้น
InvalidClassException
ในสตรีม "
main
"
java.io.InvalidClassException
และจะพิมพ์ชื่อคลาสและชื่อที่เกี่ยวข้องด้วย
SerialVersionUID
วิธีแก้ไขปัญหาอย่างรวดเร็วคือการคัดลอก
SerialVersionUID
และกำหนดให้เป็นค่าคงที่ประเภท
private
static
final
long
ในชั้นเรียนของคุณ ในบทความนี้ เราจะเรียนรู้ว่าทำไมเราจึงควรใช้
SerialVersionUID
ใน Java และวิธีใช้เครื่องมือ Serialver JDK เพื่อสร้าง ID นี้ หากคุณยังใหม่กับการทำให้เป็นอนุกรม คุณสามารถดู
คำถามสัมภาษณ์การทำให้เป็นอนุกรมของ Java 10 อันดับแรกได้ เพื่อประเมินความรู้ของคุณและค้นหาช่องว่างในความเข้าใจของคุณสำหรับการอ่านเพิ่มเติม Like
Concurrency
(เห็นพ้องต้องกัน) และ
Multi-threading
(multithreading),
Serialization
(serialization) เป็นอีกหัวข้อหนึ่งที่สมควรอ่านหลายครั้ง
เหตุใดจึงต้องใช้ SerialVersionUID ใน Java
อย่างที่ผมบอกไป เมื่อเรายังไม่ได้กำหนดค่า
SerialVersionUID
เหมือน
static
final
long
ในคลาสของเรา กลไกการทำให้ซีเรียลไลซ์จะทำแทนเรา กลไกนี้ไวต่อรายละเอียดมากมาย รวมถึงฟิลด์ของคลาสของคุณ ตัวแก้ไขการเข้าถึง อินเทอร์เฟซที่นำไปใช้ และแม้แต่การใช้งานคอมไพเลอร์ที่แตกต่างกัน การเปลี่ยนแปลงใด ๆ ในคลาสหรือการใช้คอมไพเลอร์อื่นอาจทำให้เกิดผลลัพธ์ที่แตกต่างออกไป
SerialVersionUID
ซึ่งท้ายที่สุดแล้ว หยุดข้อมูลซีเรียลไลซ์ไม่ให้โหลดซ้ำ มีความเสี่ยงที่จะต้องใช้กลไกการทำให้ซีเรียลไลซ์ของ Java เพื่อสร้างรหัสนี้ ซึ่งเป็นเหตุผลว่าทำไมจึงเป็นความคิดที่ดีที่จะกำหนดอย่างชัดเจน
SerialVersionUID
ใน
คลาส Serializableของ คุณ ฉันขอแนะนำให้อ่าน Java classic -
Joshua Bloch “Effective Java”เพื่อทำความเข้าใจการทำให้เป็นอนุกรมของ Java และปัญหาในการจัดการอย่างไม่ถูกต้อง อย่างไรก็ตาม JDK ยังมี tool
serialver
ที่อยู่ใน ไดเร็กทอรี
bin ของ ไดเร็กทอรี
JAVA_HOMEบนคอมพิวเตอร์ของฉัน
C:\Program Files\Java\jdk1.6.0_26\bin\serialver.exeซึ่งสามารถใช้ในการสร้าง
SerialVersionUID
สำหรับชั้นเรียนเก่า สิ่งนี้มีประโยชน์มากในกรณีที่คุณทำการเปลี่ยนแปลงคลาสของคุณที่ทำให้การทำให้ซีเรียลไลซ์ไม่ทำงาน และแอปพลิเคชันของคุณไม่สามารถโหลดอินสแตนซ์ซีเรียลไลซ์ซ้ำได้ คุณสามารถใช้ยูทิลิตีนี้เพื่อสร้าง
SerialVersionUID
อินสแตนซ์เก่าได้อย่างง่ายดาย จากนั้นใช้งานอย่างชัดเจนโดยการประกาศฟิลด์นี้เป็น
private static สุดท้าย long SerialVersionUID
อย่างไรก็ตาม ขอแนะนำอย่างยิ่งด้วยเหตุผลด้านประสิทธิภาพและความปลอดภัยในการใช้รูปแบบไบนารีปกติสำหรับซีเรียลไลซ์ อีกครั้ง “Effective Java” มีหลายย่อหน้าที่แสดงข้อดีของรูปแบบปกติโดยละเอียด
วิธีใช้ยูทิลิตี้ serialver JDK เพื่อสร้าง SerialVersionUID
คุณสามารถใช้
serialver
เพื่อสร้าง
SerialVersionUID
คลาสได้ สิ่งนี้มีประโยชน์อย่างยิ่งสำหรับการพัฒนาคลาส ยูทิลิตี้นี้ส่งคืน
SerialVersionUID
ในรูปแบบที่คัดลอกง่าย คุณสามารถใช้
serialver
ยูทิลิตี JDK ดังแสดงในตัวอย่าง:
$ serialver
use: serialver [-classpath classpath] [-show] [classname...]
$ serialver -classpath . Hello
Class Hello is not Serializable.
$ serialver -classpath . Hello
Hello: static final long SerialVersionUID = -4862926644813433707L;
คุณยังสามารถใช้ยูทิลิตี
serialver
เป็น
GUI
คำสั่งได้
$ serialver –show
ซึ่งจะเป็นการเปิดตัวตรวจสอบ
serial version
ซึ่งใช้ชื่อคลาสเต็มและแสดง
Serial version
ผล
สรุป
ตอนนี้เรารู้แล้วว่ามันคืออะไร
SerialVersionUID
และเหตุใดจึงสำคัญที่จะต้องประกาศมันใน
Serializable
คลาส - ถึงเวลาที่จะทบทวนข้อเท็จจริงที่สำคัญบางประการที่เกี่ยวข้องกับ Java SerialVersionUID
SerialVersionUID
ใช้เพื่อระบุเวอร์ชันของข้อมูลที่ต่อเนื่องกัน
- เมื่อเราไม่ประกาศ
SerialVersionUID
ในคลาสของเรา รันไทม์ของ Java จะทำสิ่งนั้นให้เรา แต่กระบวนการนี้ไวต่อเมตาดาต้าจำนวนมากของคลาส รวมถึงจำนวนฟิลด์ ประเภทของฟิลด์ ตัวดัดแปลงการเข้าถึงฟิลด์ อินเทอร์เฟซที่นำไปใช้ในคลาส ฯลฯ คุณสามารถค้นหาข้อมูลที่แน่นอนได้ในเอกสารการทำให้เป็นอนุกรมจาก Oracle
- ขอแนะนำให้ประกาศ SerialVersionUID เป็นตัวแปรแบบยาวสุดท้ายแบบคงที่ส่วนตัวเพื่อหลีกเลี่ยงกลไกเริ่มต้น IDE บางตัว เช่นEclipseยังออกคำเตือนหากคุณลืมสิ่งนี้ เช่น: "ลูกค้าคลาส Serializable ไม่ได้ประกาศฟิลด์ประเภท SerialVersionUID สุดท้ายแบบคงที่แบบยาว" แม้ว่าคุณจะสามารถปิดใช้งานคำเตือนนี้ได้โดยไปที่ Window > การตั้งค่า > Java > คอมไพเลอร์ > ข้อผิดพลาด/คำเตือน > ปัญหาการเขียนโปรแกรมที่อาจเกิดขึ้น ฉันขอแนะนำว่าอย่าทำเช่นนั้น เมื่อไม่จำเป็นต้องกู้คืนข้อมูลเท่านั้น ฉันจึงจะประมาทได้ นี่คือลักษณะของข้อผิดพลาดนี้ใน Eclipse IDE สิ่งที่คุณต้องทำคือตัดสินใจอย่างรวดเร็วในครั้งแรก
- คุณยังสามารถใช้ยูทิลิตี serialver จาก JDK เพื่อสร้าง Serial Version สำหรับคลาสใน Java ยูทิลิตี้นี้ยังมี GUI ซึ่งเปิดใช้งานเมื่อส่งพารามิเตอร์
show
-
- แนวทางปฏิบัติที่ดีที่สุดในการทำให้ซีเรียลไลซ์คือการประกาศอย่างชัดเจน
SerialVersionUID
เพื่อหลีกเลี่ยงปัญหาใดๆ กับการดีซีเรียลไลซ์ โดยเฉพาะอย่างยิ่งหากคุณกำลังทำงานกับแอปพลิเคชันไคลเอนต์-เซิร์ฟเวอร์ที่ต้องอาศัยข้อมูลซีเรียลไลซ์ เช่น RMI
มันคือทั้งหมดที่เกี่ยวกับ
SerialVersionUID
ใน Java ตอนนี้เรารู้แล้วว่าทำไมการประกาศให้ถูกต้อง
SerialVersionUID
ในชั้นเรียน จึงเป็นเรื่องสำคัญ คุณสามารถขอบคุณ IDE ของคุณสำหรับการแจ้งเตือนนี้ ซึ่งอาจทำให้การยกเลิกการซีเรียลไลซ์ของชั้นเรียนของคุณเสียหายได้ หากคุณต้องการอ่านเพิ่มเติมเกี่ยวกับการทำให้เป็นอนุกรมและแนวคิดที่เกี่ยวข้อง คุณสามารถดูบทความดีๆ เหล่านี้ได้
ต้นฉบับ
ที่นี่
GO TO FULL VERSION