การทำให้เป็นอันดับวัตถุคืออะไร?


384

"การทำให้เป็นอันดับวัตถุ" หมายถึงอะไร คุณช่วยอธิบายด้วยตัวอย่างได้ไหม


2
ในกรณีที่คุณสนใจสถานการณ์ Java EE ในโลกแห่งความเป็นจริงที่เกี่ยวข้องกับการทำให้เป็นอนุกรมให้มุ่งหน้าไปที่นี่: stackoverflow.com/q/2294551
BalusC

คำตอบ:


400

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


16
เป็นหน้าที่หรือไม่ ฉันต้องเป็นอันดับข้อมูลก่อนที่จะส่งหรือไม่ รูปแบบใดที่แปลงเป็น
Francisco Corrales Morales

15
@FranciscoCorralesMorales - เบื้องหลังข้อมูลทั้งหมดจะถูกทำให้เป็นอนุกรมก่อนที่จะถูกส่งผ่านสตรีม คุณต้องทำเท่าไหร่และรูปแบบของรูปแบบนั้นขึ้นอยู่กับว่าคุณใช้แพลตฟอร์มและไลบรารีใด
TarkaDaal

3
@FranciscoCorralesMorales เป็นไงบ้าง? ฉันหมายความว่าคุณกำลังบอกว่ารูปแบบขึ้นอยู่กับแพลตฟอร์มและไลบรารีฉันต้องการทราบรูปแบบ
JAVA

1
มันใช้ได้กับวัตถุเท่านั้นหรือไม่ เราสามารถทำให้เป็นอันดับตัวแปร (ประกาศโดยไม่ใช้วัตถุ)?
Rumado

@Rumado Objects เท่านั้น
anKotliner

395

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

มันมีประโยชน์มากเมื่อคุณต้องการส่งข้อมูลวัตถุหนึ่งผ่านเครือข่ายเช่นจาก JVM หนึ่งไปยังอีก

ใน Java กลไกการทำให้เป็นอันดับจะถูกสร้างขึ้นในแพลตฟอร์ม แต่คุณต้องใช้ Serializableอินเตอร์เฟซที่จะทำให้วัตถุ serializable

คุณยังสามารถป้องกันข้อมูลบางอย่างในวัตถุของคุณจากการเป็นอนุกรมโดยการทำเครื่องหมายแอตทริบิวต์เป็น ชั่วคราว

ในที่สุดคุณสามารถแทนที่กลไกเริ่มต้นและจัดเตรียมของคุณเอง; นี่อาจเหมาะสมในบางกรณีพิเศษ เมื่อต้องการทำเช่นนี้คุณใช้อย่างใดอย่างหนึ่งคุณลักษณะที่ซ่อนอยู่ใน java

สิ่งสำคัญคือให้สังเกตว่าสิ่งที่ได้รับต่อเนื่องคือ "ค่า" ของวัตถุหรือเนื้อหาไม่ใช่ข้อกำหนดของคลาส ดังนั้นวิธีการจะไม่ต่อเนื่อง

นี่คือตัวอย่างพื้นฐานที่มีความคิดเห็นเพื่อช่วยในการอ่าน:

import java.io.*;
import java.util.*;

// This class implements "Serializable" to let the system know
// it's ok to do it. You as programmer are aware of that.
public class SerializationSample implements Serializable {

    // These attributes conform the "value" of the object.

    // These two will be serialized;
    private String aString = "The value of that string";
    private int    someInteger = 0;

    // But this won't since it is marked as transient.
    private transient List<File> unInterestingLongLongList;

    // Main method to test.
    public static void main( String [] args ) throws IOException  { 

        // Create a sample object, that contains the default values.
        SerializationSample instance = new SerializationSample();

        // The "ObjectOutputStream" class has the default 
        // definition to serialize an object.
        ObjectOutputStream oos = new ObjectOutputStream( 
                               // By using "FileOutputStream" we will 
                               // Write it to a File in the file system
                               // It could have been a Socket to another 
                               // machine, a database, an in memory array, etc.
                               new FileOutputStream(new File("o.ser")));

        // do the magic  
        oos.writeObject( instance );
        // close the writing.
        oos.close();
    }
}

เมื่อเรารันโปรแกรมนี้ไฟล์ "o.ser" จะถูกสร้างขึ้นและเราสามารถเห็นสิ่งที่เกิดขึ้นข้างหลัง

หากเราเปลี่ยนค่าเป็น: someIntegerเป็นตัวอย่างเช่นInteger.MAX_VALUEเราอาจเปรียบเทียบผลลัพธ์เพื่อดูว่าความแตกต่างคืออะไร

นี่คือภาพหน้าจอที่แสดงถึงความแตกต่างอย่างแม่นยำ:

ข้อความแสดงแทน

คุณสามารถมองเห็นความแตกต่างได้หรือไม่? ;)

มีฟิลด์ที่เกี่ยวข้องเพิ่มเติมในการทำให้เป็นอันดับ Java คือ: serialversionUIDแต่ฉันเดาว่ามันยาวเกินไปที่จะครอบคลุม


1
อินสแตนซ์ @ raam86 เป็นวัตถุที่ถูกทำให้เป็นอนุกรม คุณอาจคิดในวิธีหลักเป็นโปรแกรมแยกซึ่งสร้างวัตถุประเภทSerializationSample
OscarRyz

2
@ raam86 เป็นคำสั่งแรกในวิธีการหลัก: SerializationSample instance = new SerializationSample();จากนั้นผลลัพธ์จะถูกสร้างขึ้นและวัตถุที่เขียนไปยังผลลัพธ์นั้น
OscarRyz

1
โอ้ ไม่ใกล้พอ ยิ่งใหญ่ !!
raam86

1
@jacktrades ทำไมคุณไม่ลองดู เพียงแค่คัดลอก / วางตัวอย่างและดูว่า "NotSerializableException" ถูกโยน :)
OscarRyz

1
@jacktrades เพราะคอมพิวเตอร์ไม่ได้รับการบอกกล่าวว่าวัตถุนั้นได้รับอนุญาตให้ต่อเนื่อง :) หมายความว่าอะไรโดย oos?
Chris Bennett

101

กล้าที่จะตอบคำถามอายุ 6 ปีเพิ่มความเข้าใจในระดับสูงมากสำหรับผู้ที่เพิ่งเริ่มใช้ Java

การทำให้เป็นอันดับคืออะไร

การแปลงวัตถุเป็นไบต์

Deserialization คืออะไร

การแปลงไบต์กลับเป็นวัตถุ (Deserialization)

การใช้การทำให้เป็นอันดับเมื่อใด

เมื่อเราต้องการสานต่อวัตถุ เมื่อเราต้องการให้วัตถุมีอยู่เกินกว่าอายุการใช้งานของ JVM

ตัวอย่างโลกแห่งความจริง:

ATM: เมื่อเจ้าของบัญชีพยายามถอนเงินจากเซิร์ฟเวอร์ผ่าน ATM ข้อมูลเจ้าของบัญชีเช่นรายละเอียดการถอนจะถูกทำให้เป็นอนุกรมและส่งไปยังเซิร์ฟเวอร์ที่มีการแยกรายละเอียดและใช้ในการดำเนินการ

วิธีการทำให้เป็นอนุกรมในจาวา

  1. ใช้java.io.Serializableอินเตอร์เฟส (อินเทอร์เฟซตัวทำเครื่องหมายดังนั้นจึงไม่มีวิธีนำไปใช้)

  2. คงวัตถุไว้: ใช้java.io.ObjectOutputStreamคลาสตัวกรองสตรีมซึ่งเป็น wrapper รอบ ๆ สตรีมไบต์ระดับต่ำกว่า (เพื่อเขียน Object ไปยังระบบไฟล์หรือถ่ายโอนวัตถุแบบแบนข้ามสายเครือข่ายและสร้างใหม่ในอีกด้านหนึ่ง)

    • writeObject(<<instance>>) - เพื่อเขียนวัตถุ
    • readObject() - เพื่ออ่านออบเจ็กต์ที่ต่อเนื่องกัน

โปรดจำไว้ว่า:

เมื่อคุณทำให้วัตถุเป็นอนุกรมสถานะของวัตถุเท่านั้นที่จะถูกบันทึกไม่ใช่แฟ้มคลาสหรือวิธีการ

เมื่อคุณทำอนุกรมวัตถุ 2 ไบต์คุณจะเห็นไฟล์ที่จัดลำดับ 51 ไบต์

ขั้นตอนวิธีการทำให้วัตถุเป็นอนุกรมและไม่ต่อเนื่อง

คำตอบสำหรับ: มันแปลงเป็นไฟล์ 51 ไบต์ได้อย่างไร?

  • ขั้นแรกให้เขียนข้อมูลมายากลสตรีมการทำให้เป็นอันดับ (STREAM_MAGIC = "AC ED" และ STREAM_VERSION = เวอร์ชันของ JVM)
  • จากนั้นจะเขียนข้อมูลเมตาของคลาสที่เกี่ยวข้องกับอินสแตนซ์ (ความยาวของคลาสชื่อของคลาส, serialVersionUID)
  • จากนั้นมันจะเขียนเมตาดาต้าของซูเปอร์คลาสซ้ำ ๆ จนกระทั่งพบ java.lang.Objectจนกว่าจะพบ
  • จากนั้นเริ่มต้นด้วยข้อมูลจริงที่เชื่อมโยงกับอินสแตนซ์
  • ในที่สุดก็เขียนข้อมูลของวัตถุที่เกี่ยวข้องกับอินสแตนซ์ที่เริ่มต้นจากข้อมูลเมตาไปยังเนื้อหาจริง

หากคุณสนใจข้อมูลเชิงลึกเกี่ยวกับ Java Serialization กรุณาตรวจสอบลิงค์นี้

แก้ไข : อีกหนึ่งลิงค์ที่ดีในการอ่าน

คำถามนี้จะตอบคำถามที่พบบ่อย:

  1. วิธีที่จะไม่ต่อเนื่องเขตข้อมูลใด ๆ ในชั้นเรียน
    ตอบ: ใช้คำค้นหาชั่วคราว

  2. เมื่อคลาสย่อยถูกทำให้เป็นอนุกรมคลาสแม่จะได้รับการทำให้เป็นอนุกรมหรือไม่
    ตอบ: ไม่หากผู้ปกครองไม่ได้ขยายฟิลด์ผู้ปกครองส่วนต่อประสานที่ปรับแต่งได้

  3. เมื่อใดที่ผู้ปกครองได้รับการจัดลำดับคลาสเด็กจะได้รับการทำให้เป็นอนุกรมหรือไม่
    คำตอบ: ใช่โดยค่าเริ่มต้นระดับลูกก็จะได้รับต่อเนื่อง

  4. จะหลีกเลี่ยงชั้นเรียนของเด็กไม่ให้ต่อเนื่องได้อย่างไร
    ตอบ: แทนที่ writeObject และ readObject NotSerializableExceptionวิธีการและโยน

    ข นอกจากนี้คุณสามารถทำเครื่องหมายฟิลด์ทั้งหมดชั่วคราวในคลาสเด็ก

  5. คลาสระดับระบบบางอย่างเช่น Thread, OutputStream และคลาสย่อยและ Socket ไม่สามารถทำให้เป็นอนุกรมได้

3
ขอบคุณมากสำหรับคำตอบสั้น ๆ นี้มันมีประโยชน์มาก!
บิ

21

การทำให้เป็นอันดับคือการใช้วัตถุ "สด" ในหน่วยความจำและแปลงเป็นรูปแบบที่สามารถเก็บไว้ที่ไหนสักแห่ง (เช่นในหน่วยความจำบนดิสก์) และต่อมา "deserialized" กลับเป็นวัตถุสด


14

ฉันชอบวิธีที่ @OscarRyz นำเสนอ แม้ว่าที่นี่ฉันยังคงเรื่องราวของการทำให้เป็นอันดับซึ่งเขียนโดย @amitgupta

แม้ว่าการรู้เกี่ยวกับโครงสร้างคลาสของหุ่นยนต์และการมีข้อมูลที่เป็นอนุกรมนักวิทยาศาสตร์ของโลกก็ไม่สามารถกำจัดข้อมูลที่ทำให้หุ่นยนต์ทำงานได้

Exception in thread "main" java.io.InvalidClassException:
SerializeMe; local class incompatible: stream classdesc
:

นักวิทยาศาสตร์ของดาวอังคารกำลังรอการชำระเสร็จสมบูรณ์ เมื่อการชำระเงินเสร็จสิ้นนักวิทยาศาสตร์ของดาวอังคารได้แชร์serialversionUIDกับนักวิทยาศาสตร์ของโลก นักวิทยาศาสตร์ของโลกกำหนดให้คลาสหุ่นยนต์และทุกอย่างเรียบร้อยดี


9

การทำให้เป็นอนุกรมหมายถึงวัตถุที่ยังคงอยู่ใน java หากคุณต้องการบันทึกสถานะของวัตถุและต้องการสร้างสถานะใหม่ในภายหลัง (อาจอยู่ใน JVM อื่น) การทำให้เป็นอนุกรมสามารถใช้งานได้

โปรดทราบว่าคุณสมบัติของวัตถุจะถูกบันทึกไว้เท่านั้น ถ้าคุณต้องการที่จะคืนค่าวัตถุอีกครั้งคุณควรมีไฟล์คลาสเพราะตัวแปรสมาชิกเท่านั้นจะถูกเก็บไว้และไม่ใช่ฟังก์ชั่นสมาชิก

เช่น:

ObjectInputStream oos = new ObjectInputStream(                                 
                                 new FileInputStream(  new File("o.ser")) ) ;
SerializationSample SS = (SearializationSample) oos.readObject();

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


9

My Two cents จากบล็อกของฉัน:

นี่คือคำอธิบายโดยละเอียดของการทำให้เป็นอันดับ : (บล็อกของฉันเอง)

อันดับ:

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

ความต้องการการทำให้เป็นอันดับคืออะไร?

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

ตัวอย่างรหัสและคำอธิบาย:

อันดับแรกให้ดูที่รายการระดับ:

public class Item implements Serializable{

    /**
    *  This is the Serializable class
    */
    private static final long serialVersionUID = 475918891428093041L;
    private Long itemId;
    private String itemName;
    private transient Double itemCostPrice;
    public Item(Long itemId, String itemName, Double itemCostPrice) {
        super();
        this.itemId = itemId;
        this.itemName = itemName;
        this.itemCostPrice = itemCostPrice;
      }

      public Long getItemId() {
          return itemId;
      }

     @Override
      public String toString() {
          return "Item [itemId=" + itemId + ", itemName=" + itemName + ", itemCostPrice=" + itemCostPrice + "]";
       }


       public void setItemId(Long itemId) {
           this.itemId = itemId;
       }

       public String getItemName() {
           return itemName;
       }
       public void setItemName(String itemName) {
            this.itemName = itemName;
        }

       public Double getItemCostPrice() {
            return itemCostPrice;
        }

        public void setItemCostPrice(Double itemCostPrice) {
             this.itemCostPrice = itemCostPrice;
        }
}

ในโค้ดข้างต้นจะเห็นได้ว่ารายการการดำเนินการระดับSerializable

นี่คืออินเทอร์เฟซที่เปิดใช้งานคลาสที่สามารถทำให้เป็นอนุกรมได้

ตอนนี้เราสามารถเห็นตัวแปรที่เรียกว่าserialVersionUIDนั้นถูกเตรียมใช้งานเป็นตัวแปร Long หมายเลขนี้คำนวณโดยคอมไพเลอร์ตามสถานะของคลาสและแอตทริบิวต์คลาส นี่คือหมายเลขที่จะช่วยให้ jvm ระบุสถานะของวัตถุเมื่ออ่านสถานะของวัตถุจากไฟล์

เพื่อให้เราสามารถดูเอกสารทางการของ Oracle:

ความสัมพันธ์รันไทม์ของการทำให้เป็นอนุกรมเชื่อมโยงกับหมายเลขรุ่นของคลาสที่เรียกว่า serialVersionUID ซึ่งใช้ในระหว่างการดีซีเรียลไลเซชันเพื่อตรวจสอบว่าผู้ส่งและผู้รับของวัตถุที่เป็นอนุกรมนั้นได้โหลดคลาสสำหรับวัตถุนั้นที่เข้ากันได้ หากผู้รับโหลดคลาสสำหรับวัตถุที่มี serialVersionUID ที่แตกต่างจากคลาสของผู้ส่งที่เกี่ยวข้องการดีซีเรียลไลซ์เซชั่นจะส่งผลให้เกิด InvalidClassException คลาสที่สามารถทำให้เป็นอนุกรมสามารถประกาศ serialVersionUID ของตัวเองได้อย่างชัดเจนโดยการประกาศฟิลด์ชื่อ "serialVersionUID" ที่ต้องเป็นแบบสแตติกสุดท้ายและแบบยาว: ANY-ACCESS-MODIFIER แบบคงที่แบบยาวสุดท้าย serialVersionUID = 42L; ถ้าคลาสที่สามารถทำให้เป็นอนุกรมไม่ได้ประกาศ serialVersionUID อย่างชัดเจน จากนั้นรันไทม์ของการทำให้เป็นอนุกรมจะคำนวณค่าเริ่มต้นของ serialVersionUID สำหรับคลาสนั้นตามแง่มุมต่าง ๆ ของคลาสดังที่อธิบายไว้ใน Java (TM) Object Serialization Specification อย่างไรก็ตามขอแนะนำอย่างยิ่งให้คลาสที่ทำให้เป็นอนุกรมทั้งหมดประกาศค่า serialVersionUID อย่างชัดเจนเนื่องจากการคำนวณ serialVersionUID เริ่มต้นนั้นมีความไวสูงต่อรายละเอียดของคลาสที่อาจแตกต่างกันไปขึ้นอยู่กับการใช้งานคอมไพเลอร์และอาจส่งผลให้ InvalidClassExceptions ดังนั้นเพื่อรับประกันค่า serialVersionUID ที่สอดคล้องกันระหว่างการประยุกต์ใช้คอมไพเลอร์ Java ที่แตกต่างกันคลาสที่ทำให้เป็นอนุกรมต้องประกาศค่า serialVersionUID ที่ชัดเจน ขอแนะนำอย่างชัดเจนว่าการประกาศ serialVersionUID อย่างชัดเจนใช้ตัวแก้ไขส่วนตัวหากเป็นไปได้

หากคุณสังเกตเห็นว่ามีคำหลักอื่นที่เราได้ใช้ซึ่งเป็นคำชั่วคราวชั่วคราว

หากเขตข้อมูลไม่ได้ต่อเนื่องได้จะต้องมีการทำเครื่องหมายชั่วคราว ที่นี่เราทำเครื่องหมายรายการราคาต้นทุนว่า transient และไม่ต้องการให้เขียนเป็นไฟล์

ตอนนี้เรามาดูวิธีการเขียนสถานะของวัตถุในไฟล์แล้วอ่านจากที่นั่น

public class SerializationExample {

    public static void main(String[] args){
        serialize();
       deserialize();
    } 

    public static void serialize(){

         Item item = new Item(1L,"Pen", 12.55);
         System.out.println("Before Serialization" + item);

         FileOutputStream fileOut;
         try {
             fileOut = new FileOutputStream("/tmp/item.ser");
             ObjectOutputStream out = new ObjectOutputStream(fileOut);
             out.writeObject(item);
             out.close();
             fileOut.close();
             System.out.println("Serialized data is saved in /tmp/item.ser");
           } catch (FileNotFoundException e) {

                  e.printStackTrace();
           } catch (IOException e) {

                  e.printStackTrace();
           }
      }

    public static void deserialize(){
        Item item;

        try {
                FileInputStream fileIn = new FileInputStream("/tmp/item.ser");
                ObjectInputStream in = new ObjectInputStream(fileIn);
                item = (Item) in.readObject();
                System.out.println("Serialized data is read from /tmp/item.ser");
                System.out.println("After Deserialization" + item);
        } catch (FileNotFoundException e) {
                e.printStackTrace();
        } catch (IOException e) {
               e.printStackTrace();
        } catch (ClassNotFoundException e) {
               e.printStackTrace();
        }
     }
}

ในตัวอย่างข้างต้นเราจะเห็นตัวอย่างของการทำให้เป็นอันดับและการดีซีเรียลไลเซชันของวัตถุ

เพื่อที่เราจะใช้สองชั้น สำหรับการทำให้เป็นอันดับวัตถุเราได้ใช้ ObjectOutputStream เราได้ใช้เมธอด writeObject เพื่อเขียนออบเจ็กต์ในไฟล์

สำหรับ Deserializing เราได้ใช้ ObjectInputStream ซึ่งอ่านจากวัตถุจากไฟล์ มันใช้ readObject เพื่ออ่านข้อมูลวัตถุจากไฟล์

ผลลัพธ์ของรหัสข้างต้นจะเป็นเช่น:

Before SerializationItem [itemId=1, itemName=Pen, itemCostPrice=12.55]
Serialized data is saved in /tmp/item.ser
After DeserializationItem [itemId=1, itemName=Pen, itemCostPrice=null]

ขอให้สังเกตว่าitemCostPriceจากวัตถุ deserialized เป็นโมฆะเนื่องจากไม่ได้เขียน

เราได้พูดถึงพื้นฐานของ Java Serialization แล้วในส่วนที่ฉันของบทความนี้

ตอนนี้เรามาพูดคุยกันอย่างลึกซึ้งและวิธีการทำงาน

ก่อนอื่นเรามาเริ่มด้วย serialversionuid ก่อน

The serialVersionUIDถูกนำมาใช้เป็นตัวควบคุมรุ่นในชั้นเรียน Serializable

หากคุณไม่ได้ประกาศ serialVersionUID อย่างชัดเจน JVM จะทำเพื่อคุณโดยอัตโนมัติโดยยึดตามคุณสมบัติต่าง ๆ ของคลาส Serializable

อัลกอริทึมของ Java ในการคำนวณ serialversionuid (อ่านรายละเอียดเพิ่มเติมที่นี่)

  1. ชื่อคลาส
    1. ตัวดัดแปลงคลาสที่เขียนเป็นจำนวนเต็ม 32 บิต
    2. ชื่อของแต่ละอินเตอร์เฟสเรียงตามชื่อ
    3. สำหรับแต่ละฟิลด์ของคลาสที่เรียงลำดับตามชื่อฟิลด์ (ยกเว้นฟิลด์สแตติกส่วนตัวและส่วนตัวชั่วคราว: ชื่อของฟิลด์ตัวดัดแปลงของฟิลด์ที่เขียนเป็นจำนวนเต็ม 32 บิตตัวบ่งชี้ของฟิลด์
    4. ถ้ามี initializer คลาสอยู่ให้เขียนดังต่อไปนี้: ชื่อของเมธอด,
    5. ตัวดัดแปลงของเมธอด java.lang.reflect.Modifier.STATIC ซึ่งเขียนเป็นจำนวนเต็ม 32 บิต
    6. ตัวบ่งชี้ของวิธีการ () V
    7. สำหรับตัวสร้างที่ไม่ใช่แบบส่วนตัวแต่ละรายการเรียงตามชื่อเมธอดและลายเซ็นต์: ชื่อของวิธีการ, ตัวดัดแปลงของวิธีการเขียนเป็นจำนวนเต็ม 32 บิต ตัวบ่งชี้ของวิธีการ
    8. สำหรับแต่ละวิธีที่ไม่เป็นส่วนตัวเรียงตามชื่อวิธีการและลายเซ็น: ชื่อของวิธีการ ตัวดัดแปลงของวิธีการเขียนเป็นจำนวนเต็ม 32 บิต ตัวบ่งชี้ของวิธีการ
    9. อัลกอริทึม SHA-1 ถูกเรียกใช้งานบนกระแสข้อมูลไบต์ที่สร้างโดย DataOutputStream และสร้างค่า 32- บิตห้าค่า sha [0..4] ค่าแฮชจะถูกรวบรวมจากค่า 32- บิตแรกและที่สองของการแยกย่อยข้อความ SHA-1 หากผลลัพธ์ของการแยกย่อยข้อความคำ 32- บิตห้า H0 H1 H2 H3 H4 อยู่ในอาร์เรย์ของห้าค่า int ที่ชื่อ sha ค่าแฮชจะถูกคำนวณดังนี้:
    long hash = ((sha[0] >>> 24) & 0xFF) |
>            ((sha[0] >>> 16) & 0xFF) << 8 |
>            ((sha[0] >>> 8) & 0xFF) << 16 |
>            ((sha[0] >>> 0) & 0xFF) << 24 |
>            ((sha[1] >>> 24) & 0xFF) << 32 |
>            ((sha[1] >>> 16) & 0xFF) << 40 |
>            ((sha[1] >>> 8) & 0xFF) << 48 |
>        ((sha[1] >>> 0) & 0xFF) << 56;

อัลกอริทึมการทำให้เป็นอันดับของ Java

อัลกอริทึมในการทำให้เป็นอันดับวัตถุมีคำอธิบายดังต่อไปนี้:
1. มันเขียนข้อมูลเมตาของคลาสที่เกี่ยวข้องกับอินสแตนซ์
2. เขียนซ้ำจากคำอธิบายของ superclass จนกว่าจะพบjava.lang.Object
3. เมื่อเสร็จสิ้นการเขียนข้อมูลเมตาดาต้าจากนั้นเริ่มต้นด้วยข้อมูลจริงที่เชื่อมโยงกับอินสแตนซ์ แต่ครั้งนี้มันเริ่มต้นจากซุปเปอร์คลาสสูงสุด
4. มันจะเขียนข้อมูลที่เกี่ยวข้องกับอินสแตนซ์ซ้ำโดยเริ่มจากซูเปอร์คลาสอย่างน้อยไปยังคลาสที่ได้รับมามากที่สุด

สิ่งที่ควรทราบ:

  1. ฟิลด์คงที่ในคลาสไม่สามารถต่อเนื่องกันได้

    public class A implements Serializable{
         String s;
         static String staticString = "I won't be serializable";
    }
  2. ถ้า serialversionuid แตกต่างกันในคลาสอ่านมันจะโยนInvalidClassExceptionข้อยกเว้น

  3. หากคลาสดำเนินการทำให้เป็นอนุกรมแล้วคลาสย่อยทั้งหมดจะถูกทำให้เป็นอนุกรมได้

    public class A implements Serializable {....};
    
    public class B extends A{...} //also Serializable
  4. ถ้าคลาสมีการอ้างอิงของคลาสอื่นการอ้างอิงทั้งหมดต้องเป็น Serializable มิฉะนั้นกระบวนการทำให้เป็นอนุกรมจะไม่ถูกดำเนินการ ในกรณีเช่นนี้NotSerializableExceptionจะถูกส่งไปที่รันไทม์

เช่น:

public class B{
     String s,
     A a; // class A needs to be serializable i.e. it must implement Serializable
}

1
'การทำให้เป็นอันดับเป็นกระบวนการของการทำให้เป็นอันดับสถานะของวัตถุจะถูกแสดงและจัดเก็บในรูปแบบของลำดับไบต์' นั้นไม่มีความหมาย หากserialVersionUIDจะแตกต่างกันก็จะโยนไม่InvalidClassException ClassCastExceptionไม่จำเป็นที่จะต้องเสียพื้นที่ทั้งหมดในserialVersionUIDการคำนวณ เอกสารที่ยกมามีความยาวมากเกินไป แต่ไม่ได้เชื่อมโยงหรืออ้างถึงอย่างถูกต้อง ปุยมากเกินไปที่นี่และมีข้อผิดพลาดมากเกินไป
มาร์ควิสแห่ง Lorne

'การทำให้เป็นอันดับเป็นกระบวนการของการทำให้เป็นอันดับ' ยังคงไม่มีความหมาย
มาร์ควิสแห่งลอร์น

6

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

http://en.wikipedia.org/wiki/Serialization


"... เพื่อที่จะสามารถเก็บไว้ในฮาร์ดไดรฟ์" หรือถ่ายโอนผ่านโปรโตคอลไบนารี่
จิมเดอร์สัน

4

การทำให้เป็นอันดับวัตถุ Java

ป้อนคำอธิบายรูปภาพที่นี่

Serializationเป็นกลไกในการแปลงกราฟของวัตถุ Java เป็นอาร์เรย์ของไบต์สำหรับการจัดเก็บ ( to disk file) หรือการส่ง ( across a network) จากนั้นใช้deserializationเราสามารถเรียกคืนกราฟของวัตถุ กราฟของวัตถุได้รับการกู้คืนอย่างถูกต้องโดยใช้กลไกการแบ่งปันอ้างอิง แต่ก่อนที่จะเก็บตรวจสอบว่า serialVersionUID จากอินพุตไฟล์ / เครือข่ายและ. class ไฟล์ serialVersionUID เหมือนกัน java.io.InvalidClassExceptionถ้าไม่ได้โยน

คลาสที่กำหนดเวอร์ชันแต่ละคลาสจะต้องระบุเวอร์ชันคลาสดั้งเดิมที่สามารถเขียนสตรีมและสามารถอ่านได้ ตัวอย่างเช่นคลาสที่มีเวอร์ชันต้องประกาศ:

ไวยากรณ์ของ serialVersionUID

// ANY-ACCESS-MODIFIER static final long serialVersionUID = (64-bit has)L;
private static final long serialVersionUID = 3487495895819393L;

serialVersionUIDเป็นสิ่งจำเป็นต่อกระบวนการทำให้เป็นอนุกรม แต่มันเป็นทางเลือกสำหรับนักพัฒนาเพื่อเพิ่มลงในซอร์สไฟล์ java หากไม่รวม serialVersionUID รันไทม์ของการทำให้เป็นอนุกรมจะสร้าง serialVersionUID และเชื่อมโยงกับคลาส วัตถุที่ทำให้เป็นอนุกรมจะมี serialVersionUID นี้พร้อมกับข้อมูลอื่น ๆ

หมายเหตุ - ขอแนะนำอย่างยิ่งให้คลาสที่สามารถทำให้เป็นอนุกรมทั้งหมดประกาศ serialVersionUID อย่างชัดเจนsince the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementationsและอาจส่งผลให้เกิดข้อขัดแย้ง serialVersionUID ที่ไม่คาดคิดในระหว่างการดีซีเรียลไลซ์เซชั่น

การตรวจสอบคลาสที่ต่อเนื่องกันได้

ป้อนคำอธิบายรูปภาพที่นี่


วัตถุ Java จะต่อเนื่องได้เท่านั้น ถ้าชั้นหรือใด ๆ ของ superclasses การดำเนินการของทั้งjava.io.Serializableอินเตอร์เฟซหรือ subinterface ของjava.io.Externalizable

  • คลาสต้องใช้อินเตอร์เฟส java.io.Serializableเพื่อทำให้วัตถุเป็นอนุกรมสำเร็จ Serializable เป็นอินเทอร์เฟซของตัวทำเครื่องหมายและใช้เพื่อแจ้งให้คอมไพเลอร์ทราบว่าการใช้คลาสนั้นจะต้องมีการเพิ่มลักษณะการทำงานแบบอนุกรมได้ ที่นี่ Java Virtual Machine (JVM) มีหน้าที่รับผิดชอบในการทำให้เป็นอนุกรมโดยอัตโนมัติ

    คำหลักชั่วคราว: java.io.Serializable interface

    ในขณะที่ทำให้เป็นอันดับวัตถุถ้าเราไม่ต้องการให้สมาชิกข้อมูลบางส่วนของวัตถุเป็นอนุกรมเราสามารถใช้ตัวแก้ไขชั่วคราว คำหลักชั่วคราวจะป้องกันไม่ให้สมาชิกข้อมูลนั้นถูกทำให้เป็นอนุกรม

    • เขตข้อมูลที่ประกาศเป็นชั่วคราวหรือคงที่จะถูกละเว้นโดยกระบวนการทำให้เป็นอันดับ

    ชั่วคราวและระเหย

    +--------------+--------+-------------------------------------+
    |  Flag Name   |  Value | Interpretation                      |
    +--------------+--------+-------------------------------------+
    | ACC_VOLATILE | 0x0040 | Declared volatile; cannot be cached.|
    +--------------+--------+-------------------------------------+
    |ACC_TRANSIENT | 0x0080 | Declared transient; not written or  |
    |              |        | read by a persistent object manager.|
    +--------------+--------+-------------------------------------+
    class Employee implements Serializable {
        private static final long serialVersionUID = 2L;
        static int id;
    
        int eno; 
        String name;
        transient String password; // Using transient keyword means its not going to be Serialized.
    }
  • การใช้อินเทอร์เฟซ Externalizable ช่วยให้วัตถุสามารถควบคุมเนื้อหาและรูปแบบของแบบฟอร์มต่อเนื่องของวัตถุได้อย่างสมบูรณ์ เมธอดของอินเตอร์เฟส Externalizable, writeExternal และ readExternal ถูกเรียกใช้เพื่อบันทึกและกู้คืนสถานะอ็อบเจ็กต์ เมื่อใช้งานโดยคลาสพวกเขาสามารถเขียนและอ่านสถานะของตนเองโดยใช้วิธีการทั้งหมดของ ObjectOutput และ ObjectInput มันเป็นความรับผิดชอบของวัตถุที่จะจัดการกับเวอร์ชันใด ๆ ที่เกิดขึ้น

    class Emp implements Externalizable {
        int eno; 
        String name;
        transient String password; // No use of transient, we need to take care of write and read.
    
        @Override
        public void writeExternal(ObjectOutput out) throws IOException {
            out.writeInt(eno);
            out.writeUTF(name);
            //out.writeUTF(password);
        }
        @Override
        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            this.eno = in.readInt();
            this.name = in.readUTF();
            //this.password = in.readUTF(); // java.io.EOFException
        }
    }
  • เฉพาะอ็อบเจ็กต์ที่สนับสนุนอินเตอร์เฟส java.io.Serializable หรือ java.io.Externalizable เท่านั้นที่สามารถwritten to/read fromสตรีม คลาสของแต่ละวัตถุที่สามารถทำให้เป็นอนุกรมได้ถูกเข้ารหัสรวมถึงชื่อคลาสและลายเซ็นของคลาสค่าของเขตข้อมูลและอาร์เรย์ของวัตถุและการปิดวัตถุอื่น ๆ ที่อ้างอิงจากวัตถุเริ่มต้น

ตัวอย่างที่ทำให้ต่อเนื่องสำหรับไฟล์

public class SerializationDemo {
    static String fileName = "D:/serializable_file.ser";

    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
        Employee emp = new Employee( );
        Employee.id = 1; // Can not Serialize Class data.
        emp.eno = 77;
        emp.name = "Yash";
        emp.password = "confidential";
        objects_WriteRead(emp, fileName);

        Emp e = new Emp( );
        e.eno = 77;
        e.name = "Yash";
        e.password = "confidential";
        objects_WriteRead_External(e, fileName);

        /*String stubHost = "127.0.0.1";
        Integer anyFreePort = 7777;
        socketRead(anyFreePort); //Thread1
        socketWrite(emp, stubHost, anyFreePort); //Thread2*/

    }
    public static void objects_WriteRead( Employee obj, String serFilename ) throws IOException{
        FileOutputStream fos = new FileOutputStream( new File( serFilename ) );
        ObjectOutputStream objectOut = new ObjectOutputStream( fos );
        objectOut.writeObject( obj );
        objectOut.close();
        fos.close();

        System.out.println("Data Stored in to a file");

        try {
            FileInputStream fis = new FileInputStream( new File( serFilename ) );
            ObjectInputStream ois = new ObjectInputStream( fis );
            Object readObject;
            readObject = ois.readObject();
            String calssName = readObject.getClass().getName();
            System.out.println("Restoring Class Name : "+ calssName); // InvalidClassException

            Employee emp = (Employee) readObject;
            System.out.format("Obj[No:%s, Name:%s, Pass:%s]", emp.eno, emp.name, emp.password);

            ois.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    public static void objects_WriteRead_External( Emp obj, String serFilename ) throws IOException {
        FileOutputStream fos = new FileOutputStream(new File( serFilename ));
        ObjectOutputStream objectOut = new ObjectOutputStream( fos );

        obj.writeExternal( objectOut );
        objectOut.flush();

        fos.close();

        System.out.println("Data Stored in to a file");

        try {
            // create a new instance and read the assign the contents from stream.
            Emp emp = new Emp();

            FileInputStream fis = new FileInputStream(new File( serFilename ));
            ObjectInputStream ois = new ObjectInputStream( fis );

            emp.readExternal(ois);

            System.out.format("Obj[No:%s, Name:%s, Pass:%s]", emp.eno, emp.name, emp.password);

            ois.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

ตัวอย่างที่ทำให้เป็นอนุกรมผ่านเครือข่าย

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

/**
 * Creates a stream socket and connects it to the specified port number on the named host. 
 */
public static void socketWrite(Employee objectToSend, String stubHost, Integer anyFreePort) {
    try { // CLIENT - Stub[marshalling]
        Socket client = new Socket(stubHost, anyFreePort);
        ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream());
        out.writeObject(objectToSend);
        out.flush();
        client.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
// Creates a server socket, bound to the specified port. 
public static void socketRead(  Integer anyFreePort ) {
    try { // SERVER - Stub[unmarshalling ]
        ServerSocket serverSocket = new ServerSocket( anyFreePort );
        System.out.println("Server serves on port and waiting for a client to communicate");
            /*System.in.read();
            System.in.read();*/

        Socket socket = serverSocket.accept();
        System.out.println("Client request to communicate on port server accepts it.");

        ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
        Employee objectReceived = (Employee) in.readObject();
        System.out.println("Server Obj : "+ objectReceived.name );

        socket.close();
        serverSocket.close();
    } catch (IOException | ClassNotFoundException e) {
        e.printStackTrace();
    }
}

@ดู


1
เมื่อคุณเพิ่มคำตอบให้กับคำถามอายุหกขวบที่มีคำตอบที่ดีมากอยู่แล้วคุณต้องทำดีกว่าเสียงขรมของข้อผิดพลาดในการสะกดคำ
มาร์ควิสแห่ง Lorne

@ejp Downvoting เป็นเครื่องมือในการแสดงความคิดเห็นเชิงลบของคุณ การเป็นคนก้าวร้าวและแนวเขตแดนหยาบคายเป็นสิ่งที่ยอมรับไม่ได้
Konstantinos Chertouras

1
@KonstantinosChertouras การให้เหตุผลสำหรับการโหวตมีประโยชน์กับโปสเตอร์และนั่นคือเหตุผลของฉันเช่นพวกเขาหรือไม่อย่างที่คุณต้องการ
มาร์ควิสแห่ง Lorne

คุณต้องหลีกเลี่ยงข้อผิดพลาดเช่นยืนยันว่าการทำให้เป็นอนุกรมมีวัตถุประสงค์ด้านความปลอดภัย มันไม่ได้
มาร์ควิสแห่ง Lorne

@EJP ฉันได้อัปเดตโพสต์ของฉันแก้ไขว่าการทำให้เป็นอันดับไม่ใช่เพื่อความปลอดภัย แต่ใช้เพื่อแปลงสถานะของวัตถุเป็นที่เก็บข้อมูลใด ๆ และเพื่อให้ได้สถานะดั้งเดิมของวัตถุกลับมาโดยใช้ SUID ผ่านกลไกการกำจัด JVM to JVM
Yash

3

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

วัตถุที่จะต่อเนื่องจะต้องใช้java.io.SerializableInterface กลไกการทำให้เป็นอนุกรมเริ่มต้นสำหรับวัตถุเขียนคลาสของวัตถุ, ลายเซ็นคลาสและค่าของเขตข้อมูลที่ไม่ใช่แบบชั่วคราวและไม่คงที่ทั้งหมด

class ObjectOutputStream extends java.io.OutputStream implements ObjectOutput,

ObjectOutputinterface ขยายDataOutputอินเตอร์เฟสและเพิ่มวิธีสำหรับซีเรียลไลซ์เซชันของวัตถุและการเขียนไบต์ไปยังไฟล์ ส่วนต่อObjectOutputStreamขยายjava.io.OutputStreamและใช้งานObjectOutput อินเตอร์เฟส มันซีเรียลไลซ์วัตถุอาร์เรย์และค่าอื่น ๆ กับสตรีม ดังนั้นตัวสร้างของ ObjectOutputStreamถูกเขียนเป็น:

ObjectOutput ObjOut = new ObjectOutputStream(new FileOutputStream(f));

โค้ดด้านบนถูกใช้เพื่อสร้างอินสแตนซ์ของObjectOutputคลาสด้วยตัวObjectOutputStream( )สร้างซึ่งใช้อินสแตนซ์ของFileOuputStreamพารามิเตอร์

ObjectOutputอินเตอร์เฟซที่ใช้งานโดยการดำเนินการObjectOutputStreamระดับ ObjectOutputStreamถูกสร้างขึ้นมาเพื่อเป็นอันดับวัตถุ

การดีซีเรียลไลซ์วัตถุใน java

การดำเนินการตรงข้ามของการทำให้เป็นอนุกรมเรียกว่าดีซีเรียลไลเซชั่นคือการดึงข้อมูลจากชุดของไบต์เป็นที่รู้จักกันในชื่อดีซีเรียลไลเซชั่น

ObjectInputStreamขยายjava.io.InputStreamและใช้ObjectInput อินเตอร์เฟส มัน deserializes วัตถุอาร์เรย์และค่าอื่น ๆ จากการป้อนข้อมูล ดังนั้นตัวสร้างของ ObjectInputStreamถูกเขียนเป็น:

ObjectInputStream obj = new ObjectInputStream(new FileInputStream(f));

โค้ดด้านบนของโปรแกรมสร้างอินสแตนซ์ของObjectInputStreamคลาสเพื่อยกเลิกการซีเรียลObjectInputStreamไลซ์ไฟล์ที่ถูกทำให้เป็นอนุกรมโดยคลาส รหัสข้างต้นสร้างอินสแตนซ์โดยใช้อินสแตนซ์ของFileInputStreamคลาสที่เก็บวัตถุไฟล์ที่ระบุซึ่งจะต้องมีการ deserialized เพราะคอนObjectInputStream()สตรัคต้องการกระแสข้อมูล


2

การทำให้เป็นอันดับเป็นกระบวนการของการเปลี่ยนวัตถุ Java เป็นอาร์เรย์ไบต์แล้วกลับมาเป็นวัตถุอีกครั้งด้วยสถานะที่สงวนไว้ มีประโยชน์สำหรับสิ่งต่าง ๆ เช่นการส่งวัตถุผ่านเครือข่ายหรือแคชสิ่งของลงดิสก์

อ่านข้อมูลเพิ่มเติมจากบทความสั้น ๆ นี้ซึ่งจะอธิบายการเขียนโปรแกรมเป็นส่วนหนึ่งของกระบวนการที่ค่อนข้างดีและจากนั้นย้ายไปยังที่จะJavadoc Serializable คุณอาจสนใจอ่านคำถามที่เกี่ยวข้องนี้


2

ส่งคืนไฟล์เป็นวัตถุ: http://www.tutorialspoint.com/java/java_serialization.htm

        import java.io.*;

        public class SerializeDemo
        {
           public static void main(String [] args)
           {
              Employee e = new Employee();
              e.name = "Reyan Ali";
              e.address = "Phokka Kuan, Ambehta Peer";
              e.SSN = 11122333;
              e.number = 101;

              try
              {
                 FileOutputStream fileOut =
                 new FileOutputStream("/tmp/employee.ser");
                 ObjectOutputStream out = new ObjectOutputStream(fileOut);
                 out.writeObject(e);
                 out.close();
                 fileOut.close();
                 System.out.printf("Serialized data is saved in /tmp/employee.ser");
              }catch(IOException i)
              {
                  i.printStackTrace();
              }
           }
        }

    import java.io.*;
    public class DeserializeDemo
    {
       public static void main(String [] args)
       {
          Employee e = null;
          try
          {
             FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
             ObjectInputStream in = new ObjectInputStream(fileIn);
             e = (Employee) in.readObject();
             in.close();
             fileIn.close();
          }catch(IOException i)
          {
             i.printStackTrace();
             return;
          }catch(ClassNotFoundException c)
          {
             System.out.println("Employee class not found");
             c.printStackTrace();
             return;
          }
          System.out.println("Deserialized Employee...");
          System.out.println("Name: " + e.name);
          System.out.println("Address: " + e.address);
          System.out.println("SSN: " + e.SSN);
          System.out.println("Number: " + e.number);
        }
    }

สิ่งนี้ไม่ได้ตอบ 'ส่วนที่เป็น' หรือ 'โปรดอธิบาย' ส่วนของคำถาม
มาร์ควิสแห่ง Lorne

1

| * | การทำให้คลาสเป็นอนุกรม: การแปลงวัตถุเป็นไบต์และไบต์กลับไปเป็นวัตถุ (Deserialization)

class NamCls implements Serializable
{
    int NumVar;
    String NamVar;
}

| => Object-Serialization เป็นกระบวนการของการแปลงสถานะของวัตถุเป็นจำนวนเต็มไบต์

  • | -> ใช้งานเมื่อคุณต้องการวัตถุที่มีอยู่เกินอายุการใช้งานของ JVM
  • | -> วัตถุที่เป็นอนุกรมสามารถจัดเก็บในฐานข้อมูล
  • | -> มนุษย์ไม่สามารถอ่านและเข้าใจวัตถุที่ต่อเนื่องกันได้ดังนั้นเราจึงสามารถรักษาความปลอดภัยได้

| => Object-Deserialization เป็นกระบวนการรับสถานะของวัตถุและเก็บไว้ในวัตถุ (java.lang.Object)

  • | -> ก่อนการจัดเก็บสถานะจะตรวจสอบว่ารูปแบบ serialVersionUID อินพุตไฟล์ / เครือข่ายและไฟล์. classclassVersionUID เหมือนกันหรือไม่
    & nbsp & nbsp หากไม่ได้โยน java.io.InvalidClassException

| => วัตถุ Java นั้นสามารถทำให้เป็นอนุกรมได้หากคลาสหรือซูเปอร์คลาสใด ๆ

  • ใช้อินเตอร์เฟส java.io.Serializable หรือ
  • หน้าย่อยของมัน java.io.Externalable

| => ฟิลด์คงที่ในคลาสไม่สามารถต่อเนื่องกันได้

class NamCls implements Serializable
{
    int NumVar;
    static String NamVar = "I won't be serializable";;
}

| => หากคุณไม่ต้องการทำให้เป็นอนุกรมของคำสำคัญการใช้คลาสชั่วคราว

class NamCls implements Serializable
{
    int NumVar;
    transient String NamVar;
}

| => หากคลาสดำเนินการทำให้เป็นอนุกรมแล้วคลาสย่อยทั้งหมดของคลาสนั้นจะเป็นแบบอนุกรม

| => ถ้าคลาสมีการอ้างอิงของคลาสอื่นการอ้างอิงทั้งหมดต้องเป็นแบบอนุกรมได้มิฉะนั้นกระบวนการทำให้เป็นอนุกรมจะไม่ถูกดำเนินการ ในกรณีเช่นนี้
NotSerializableException จะถูกส่งไปที่รันไทม์


0

ฉันจะเสนอการเปรียบเทียบเพื่อช่วยในการทำให้วัตถุประสงค์เชิงแนวคิด / การปฏิบัติจริงของวัตถุเป็นอนุกรม / การดีซีเรียลไลซ์เซชันเป็นจริง

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

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

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