เมื่อใดที่เราควรใช้อินเตอร์เฟซแบบอนุกรม


153
public class Contact implements Serializable {
    private String name;
    private String email;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}
  1. ฉันควรใช้Serializableส่วนต่อประสานเมื่อใด
  2. ทำไมเราทำเช่นนั้น?
  3. มันให้ข้อดีหรือความปลอดภัยหรือไม่?

1
FYI คำตอบที่ยอมรับได้ที่นี่ไม่สมบูรณ์และทำให้เข้าใจผิดเนื่องจากไม่ได้ระบุข้อบกพร่องด้านความปลอดภัย ดูJava ที่มีประสิทธิภาพ , รายการที่ 86: ปรับใช้ Serializable ได้อย่างระมัดระวัง คำตอบของ Raedwald ที่นี่ว่าไม่ใช้การทำให้เป็นอันดับเป็นสิ่งที่ถูกต้อง
นาธานฮิวจ์

คำตอบ:


157
  1. จากสิ่งนี้คืออะไร "อนุกรม" สิ่งทั้งหมดเกี่ยวกับ? :

    มันช่วยให้คุณสามารถนำวัตถุหรือกลุ่มของวัตถุวางลงบนดิสก์หรือส่งผ่านลวดหรือกลไกการส่งไร้สายหลังจากนั้นอาจใช้คอมพิวเตอร์อีกเครื่องหนึ่งในกระบวนการย้อนกลับ: คืนชีพวัตถุเดิม กลไกพื้นฐานคือการแผ่วัตถุ (s) ให้เป็นกระแสหนึ่งมิติของบิตและเปลี่ยนกระแสของบิตนั้นกลับเข้าไปในวัตถุดั้งเดิม

    เช่น Transporter ใน Star Trek ทุกอย่างเกี่ยวกับการทำสิ่งที่ซับซ้อนและทำให้มันกลายเป็นลำดับที่แบนราบของ 1s และ 0s จากนั้นนำลำดับของ 1s และ 0s (อาจไปอยู่ที่อื่นในเวลาอื่น) และสร้างความซับซ้อนดั้งเดิมขึ้นใหม่ " บางสิ่งบางอย่าง."

    ดังนั้นใช้Serializableอินเทอร์เฟซเมื่อคุณต้องการเก็บสำเนาของวัตถุส่งไปยังกระบวนการอื่นซึ่งทำงานบนระบบเดียวกันหรือผ่านเครือข่าย

  2. เพราะคุณต้องการที่จะจัดเก็บหรือส่งวัตถุ

  3. ทำให้การจัดเก็บและส่งวัตถุเป็นเรื่องง่าย มันไม่มีอะไรเกี่ยวข้องกับความปลอดภัย


4
มันเป็นวิธีปฏิบัติที่ดีที่สุดในการใช้ส่วนต่อประสาน seriablizble กับทุกรุ่นของโดเมน ...
theJava

8
@theJava ไม่ใช่คำถามของแนวทางปฏิบัติที่ดีที่สุด มันเป็นคำถามว่าคุณต้องการซีรีย์ของไบต์หรือไม่
moinudin

5
เมื่อใช้ JSON คุณไม่จำเป็นต้องใช้อินเทอร์เฟซนี้และสามารถส่งสตริงนั้นได้ดังนั้นฉันยังไม่แน่ใจว่าทำไมต้องใช้อินเทอร์เฟซนี้เมื่อคุณสามารถใช้ JSON ได้
Yonatan Nir

1
@YonatanNir ฉันไม่แน่ใจว่าทำไมคนจะใช้ JSON เมื่อ MsgPack, Avro, Thrift หรือ Protobuf ดีกว่าสำหรับการถ่ายโอน IO
OneCricketeer

1
@YonatanNir สคีมาที่กำหนดไว้อย่างเคร่งครัดดีกว่า และ JSON นั้นมนุษย์สามารถอ่านได้ในขณะที่รูปแบบการเข้ารหัสแบบไบนารีนั้นมีประสิทธิภาพมากกว่าการใช้สาย
OneCricketeer

48
  1. ใช้Serializableอินเทอร์เฟซเมื่อคุณต้องการแปลงอินสแตนซ์ของคลาสเป็นชุดของไบต์หรือเมื่อคุณคิดว่าSerializableวัตถุอาจอ้างอิงอินสแตนซ์ของคลาสของคุณ

  2. Serializable คลาสมีประโยชน์เมื่อคุณต้องการคงอินสแตนซ์ของพวกมันหรือส่งผ่านสาย

  3. กรณีของSerializableชั้นเรียนสามารถส่งได้อย่างง่ายดาย การทำให้เป็นอนุกรมจะมีผลกระทบด้านความปลอดภัยบางประการ อ่านโจชัวโบลชJava ที่มีประสิทธิภาพ


32

คำตอบสำหรับคำถามนี้อาจจะแปลกใจ ไม่เคยหรือมากกว่าแนบเนียนเฉพาะเมื่อคุณถูกบังคับให้ทำงานร่วมกันกับรหัสเดิม นี่คือคำแนะนำในEffective Java, 3rd Editionโดย Joshua Bloch:

ไม่มีเหตุผลที่จะใช้การทำให้เป็นอันดับ Java ในระบบใหม่ใด ๆ ที่คุณเขียน

Mark Reinhold หัวหน้าสถาปนิกของออราเคิลกำลังทำสถิติสูงสุด ว่าการลบกลไกการจัดลำดับ Java ปัจจุบันเป็นเป้าหมายระยะยาว


ทำไมการทำให้ซีเรียลไลซ์เซชั่นของ Java มีข้อบกพร่อง

Java จัดให้เป็นส่วนหนึ่งของภาษาของรูปแบบการทำให้เป็นอันดับซึ่งคุณสามารถเลือกใช้โดยใช้Serializableส่วนต่อประสาน รูปแบบนี้มีข้อบกพร่องที่ดื้อดึงหลายประการและควรถือว่าเป็นการทดสอบที่ล้มเหลวโดยนักออกแบบภาษา Java

  • มันลึกซึ้งแสร้งทำเป็นว่าสามารถพูดคุยเกี่ยวกับแบบฟอร์มต่อเนื่องของวัตถุ แต่มีรูปแบบการทำให้เป็นอนุกรมจำนวนมากอย่างไม่ จำกัด ทำให้เกิดรูปแบบที่เป็นอนุกรมจำนวนมากอย่างไม่ จำกัด โดยการกำหนดรูปแบบหนึ่งโดยไม่ต้องเปลี่ยนรูปแบบใด ๆ แอปพลิเคชันไม่สามารถใช้รูปแบบที่เหมาะสมที่สุดสำหรับพวกเขา
  • มันถูกนำมาใช้เป็นวิธีการเพิ่มเติมของการสร้างวัตถุซึ่งข้ามเงื่อนไขใด ๆ ที่ตรวจสอบการก่อสร้างของคุณหรือวิธีการโรงงานดำเนินการ ยกเว้นในกรณีที่มีข้อผิดพลาดมีแนวโน้มที่จะเกิดข้อผิดพลาดและยากในการทดสอบรหัสการลดความเสี่ยงพิเศษรหัสของคุณอาจมีจุดอ่อนด้านความปลอดภัยที่อ้าปากค้าง
  • การทดสอบการทำงานร่วมกันของเวอร์ชันที่แตกต่างกันของแบบฟอร์มต่อเนื่องนั้นยากมาก
  • การจัดการกับวัตถุที่ไม่เปลี่ยนรูปนั้นเป็นสิ่งที่ลำบาก

จะทำอย่างไรแทน

ใช้โครงร่างการทำให้เป็นอนุกรมแทนซึ่งคุณสามารถควบคุมได้อย่างชัดเจนแทน เช่น Protocol Buffers, JSON, XML หรือโครงร่างที่กำหนดเองของคุณเอง


2
ไม่มากของผู้เชี่ยวชาญในระดับนั้น แต่รู้สึกว่าคุณมีจุด
nightfury

1
ฉันคิดว่ามันเป็นคำตอบที่ดีที่สุด!
jjanczur
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.