JavaRush /จาวาบล็อก /Random-TH /การทำให้เป็นอนุกรมทำงานอย่างไรใน Java
ramhead
ระดับ

การทำให้เป็นอนุกรมทำงานอย่างไรใน Java

เผยแพร่ในกลุ่ม
ในบทความนี้ เราจะอธิบายว่าการทำให้เป็นอนุกรมคืออะไรและทำงานอย่างไรใน Java การทำให้เป็นอนุกรมทำงานอย่างไรใน Java - 1

การแนะนำ

การทำให้เป็นอนุกรมของออบเจ็กต์คือความสามารถของออบเจ็กต์ในการจัดเก็บสำเนาที่สมบูรณ์ของตัวเองและออบเจ็กต์อื่น ๆ ที่อ้างอิงโดยใช้สตรีมเอาต์พุต (เช่น ไปยังไฟล์ภายนอก) ด้วยวิธีนี้ วัตถุจะถูกสร้างขึ้นใหม่จากสำเนาซีเรียลไลซ์ (ที่บันทึกไว้) ในภายหลังเล็กน้อยเมื่อจำเป็น การทำให้เป็นอนุกรมของอ็อบเจ็กต์เป็นคุณสมบัติใหม่ที่นำมาใช้ใน JDK 1.1 มีฟังก์ชันสำหรับการแปลงกลุ่มหรืออ็อบเจ็กต์แต่ละรายการให้เป็นบิตสตรีมหรืออาร์เรย์ไบต์ สำหรับการจัดเก็บหรือการส่งผ่านเครือข่าย และตามที่ระบุไว้ บิตสตรีมหรืออาร์เรย์ไบต์ที่กำหนดสามารถแปลงกลับเป็นอ็อบเจ็กต์ Java ได้ สิ่งนี้ส่วนใหญ่เกิดขึ้นโดย อัตโนมัติด้วย คลาส ObjectInputStreamและ ObjectOutputStreamโปรแกรมเมอร์อาจตัดสินใจที่จะใช้ฟังก์ชันนี้โดยการใช้อินเทอร์เฟซSerializableเมื่อสร้างคลาส กระบวนการทำให้เป็นอนุกรมเรียกอีกอย่างว่า object marshalingในขณะที่การดีซีเรียลไลซ์เรียกว่าunmarshaling การทำให้เป็นอนุกรมเป็นกลไกที่อนุญาตให้ออบเจ็กต์บันทึกสำเนาของตัวเองและออบเจ็กต์อื่น ๆ ทั้งหมดที่อ้างอิงโดยออบเจ็กต์นั้นไปยังไฟล์ภายนอกโดยใช้นามสกุลObjectOutputStream. ออบเจ็กต์ที่บันทึกไว้อาจเป็นโครงสร้างข้อมูล ไดอะแกรม ออบเจ็กต์คลาสJFrameหรือออบเจ็กต์อื่นใด โดยไม่คำนึงถึงประเภทของออบเจ็กต์ ในเวลาเดียวกัน การซีเรียลไลซ์จะเก็บข้อมูลเกี่ยวกับประเภทของออบเจ็กต์ เพื่อว่าในภายหลังเมื่อดีซีเรียลไลซ์ ข้อมูลนั้นจะถูกใช้เพื่อสร้างประเภทออบเจ็กต์ที่แน่นอนอีกครั้ง ดังนั้นการทำให้เป็นอนุกรมจึงมีความสามารถดังต่อไปนี้:
  • ระบบสำหรับจัดเก็บอ็อบเจ็กต์ เช่น การบันทึกคุณสมบัติลงในไฟล์ภายนอก ลงดิสก์ หรือในฐานข้อมูล
  • ระบบเรียกขั้นตอนระยะไกล
  • ระบบการกระจายออบเจ็กต์ ตัวอย่างเช่น ในส่วนประกอบซอฟต์แวร์ เช่น COM, COBRA
  • ระบบระบุการเปลี่ยนแปลงของข้อมูลตัวแปรในช่วงเวลาหนึ่ง
เพื่อให้เข้าใจแนวคิดของการซีเรียลไลซ์อย่างถ่องแท้ คุณต้องมีความเข้าใจที่ชัดเจนของอีกสองแนวคิด—การคงอยู่ของอ็อบเจ็กต์และการคงอยู่ของเธรด ที่นี่เราจะพูดถึงแต่ละเรื่องเล็กน้อยเพื่อที่จะจดจำ คำอธิบายโดยละเอียดจะต้องมีบทแยกต่างหากสำหรับแต่ละแนวคิดเหล่านี้

สตรีม:

ทุกโปรแกรมจะต้องเขียนข้อมูลไปยังตำแหน่งหน่วยเก็บข้อมูลหรือไปป์ และทุกโปรแกรมจะต้องอ่านข้อมูลจากไปป์หรือตำแหน่งหน่วยเก็บข้อมูล ใน Java ช่องทางเหล่านี้ที่โปรแกรมเขียนถึงและจาก ที่ โปรแกรมอ่านข้อมูลเรียกว่าStreams ( Stream)การทำให้เป็นอนุกรมทำงานอย่างไรใน Java - 2
รูปที่ 1 การแสดงเธรดแบบกราฟิก
สตรีมแบ่งออกเป็นสองประเภทหลัก:
  • คลาสสตรีมไบต์ที่เรียกว่า *Streams
  • คลาสสตรีมอักขระที่เรียกว่า *Reader และ *Writer
สตรีมการเขียนข้อมูลแต่ละรายการประกอบด้วยชุดวิธีการเขียน และแต่ละเธรดการอ่านข้อมูลก็มีชุดวิธีการอ่านที่คล้ายกัน เมื่อสร้างเธรดแล้ว จะต้องเรียกใช้เมธอดเหล่านี้ทั้งหมด

วิริยะ

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

การใช้งานอินเทอร์เฟซแบบอนุกรม

คลาสใด ๆ ต้องใช้อินเทอร์เฟซjava.io.Serializableเพื่อทำให้วัตถุเป็นอนุกรมของคลาสนั้น อินเทอร์เฟซSerializableไม่มีวิธีการและทำเครื่องหมายเฉพาะคลาสเพื่อให้สามารถระบุเป็นอนุกรมได้ สามารถบันทึกได้เฉพาะฟิลด์ของอ็อบเจ็กต์คลาสซีเรียลไลซ์เท่านั้น วิธีการหรือตัวสร้างจะไม่ถูกจัดเก็บเป็นส่วนหนึ่งของกระแสข้อมูลแบบอนุกรม หากวัตถุใดทำหน้าที่เป็นการอ้างอิงไปยังวัตถุอื่น ฟิลด์ของวัตถุนั้นก็จะถูกทำให้เป็นอนุกรมเช่นกัน หากคลาสของวัตถุนั้นใช้อินเทอร์เฟSerializableซ กล่าวอีกนัยหนึ่ง กราฟของวัตถุนี้ที่ได้รับจึงสามารถทำให้เป็นอนุกรมได้อย่างสมบูรณ์ กราฟวัตถุประกอบด้วยแผนภูมิหรือโครงสร้างของช่องของวัตถุและวัตถุย่อย สองคลาสหลักที่ช่วยปรับใช้อินเทอร์เฟซSeriliazable:
  • ObjectInputStream
  • ObjectOutputStream
รายการ 1. ตัวอย่างของคลาสอย่างง่ายในการแสดงการทำให้เป็นอนุกรม
import java.io.*;
public class RandomClass implements Serializable {
 // Генерация рандомного значения
 private static int r() {
        return (int)(Math.random() * 10);
 }
    private int data[];
    // Конструктор
public RandomClass() {
        datafile = new int[r()];
        for (int i=0; i<datafile.length; i++)
        datafile[i]=r();
 }
    public void printout() {
 System.out.println("This RandomClass has "+datafile.length+" random integers");
 for (int i=0; i<datafile.length; i++) {
        System.out.print(datafile[i]+":");
        System.out.println();
    }
}
ในโค้ดข้างต้น มีการสร้างคลาสที่สามารถซีเรียลไลซ์ได้เนื่องจาก "ทำเครื่องหมาย" โดยอินเทอร์เฟซการทำให้เป็นอนุกรม คลาสจะสร้างอาร์เรย์ของจำนวนเต็มสุ่มเมื่อมีการสร้างอินสแตนซ์ขึ้นมา โค้ดด้านล่างแสดงความสามารถในการเขียนออบเจ็กต์ไปยังสตรีมโดยใช้ส่วนขยายObjectOutputStream. โปรแกรมมีอาร์เรย์ของจำนวนเต็ม แต่สำหรับการทำให้เป็นอนุกรม เราไม่จำเป็นต้องวนซ้ำอ็อบเจ็กต์ภายใน อินเทอร์เฟซSeriliazableจะดูแลสิ่งนี้โดยอัตโนมัติ รายการ 2 ตัวอย่างง่ายๆ ของการทำให้วัตถุเป็นอนุกรมสำหรับเอาต์พุตไปยังไฟล์
import java.io.*;
import java.util.*;
public class OutSerialize {
    public static void main (String args[]) throws IOException {
        RandomClass rc1 = new RandomClass();
        RandomClass rc2 = new RandomClass();
//создание цепи потоков с потоком вывода an object в конце
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("objects.dat"));
        Date now = new Date(System.currentTimeMillis());
//java.util.* был импортирован для использования класса Date
        out.writeObject(now);
        out.writeObject(rc1);
        out.writeObject(rc2);
out.close();
        System.out.println("I have written:");
System.out.println("A Date object: "+now);
        System.out.println("Two Group of randoms");
rc1.printout();
rc2.printout();
 }
}
โค้ดด้านล่างแสดงให้เห็นถึงความสามารถของคลาสObjectInputStreamซึ่งอ่านข้อมูลซีเรียลไลซ์จากไฟล์ภายนอกลงในโปรแกรม โปรดทราบว่าวัตถุจะถูกอ่านในลำดับเดียวกับที่เขียนลงในไฟล์ รายการ 3. การอ่านวัตถุแบบอนุกรมหรือการดีซีเรียลไลซ์
import java.io.*;
import java.util.*;
public class InSerialize {
 public static void main (String args[]) throws  IOException, ClassNotFoundException {
    ObjectInputStream in =  new ObjectInputStream (new FileInputStream("objects.dat"));
 Date d1 = (Date)in.readObject();
 RandomClass rc1 = (RandomClass)in.readObject();
    RandomClass rc2 = (RandomClass)in.readObject();
    System.out.println("I have read:");
    System.out.println("A Date object: "+d1);
    System.out.println("Two Group of randoms");
    rc1.printout();
rc2.printout();
 }
}
คลาส Java เกือบทั้งหมดสามารถซีเรียลไลซ์ได้ รวมถึงคลาส AWT เฟรม ซึ่งเป็นหน้าต่าง ประกอบด้วยชุดของส่วนประกอบกราฟิก หากเฟรมถูกทำให้เป็นอนุกรม โปรแกรมทำให้เป็นอนุกรมจะดูแลสิ่งนี้และทำให้เป็นอนุกรมส่วนประกอบและข้อมูลทั้งหมด (ตำแหน่ง เนื้อหา ฯลฯ) อ็อบเจ็กต์คลาส Java บางตัวไม่สามารถทำให้เป็นอนุกรมได้เนื่องจากมีข้อมูลที่อ้างอิงถึงทรัพยากรระบบปฏิบัติการชั่วคราว เช่น คลาสjava.io.FileInputStreamและjava.lang.Thread. หากออบเจ็กต์มีการอ้างอิงถึงองค์ประกอบที่ไม่ทำให้เป็นอนุกรม การดำเนินการทำให้เป็นอนุกรมทั้งหมดจะล้มเหลวและข้อยกเว้นจะถูกส่งออกNotSerializableExceptionไป หากอ็อบเจ็กต์ใดๆ อ้างถึงการ อ้างอิง ของอ็อบเจ็กต์ที่ไม่ต่อเนื่อง ก็สามารถทำให้เป็นอนุกรมได้โดยใช้ คีย์เวิร์ด ชั่วคราว รายการ 4 การสร้างออบเจ็กต์ที่ทำให้ซีเรียลไลซ์ได้โดยใช้ คีย์เวิร์ดชั่วคราว
public class Sclass implements Serializable{
public transient Thread newThread;
//помните, что поток(поток параллельного исполнения) по умолчанию не сериализуемый класс
    private String studentID;
    private int sum;
}

ความปลอดภัยในการทำให้เป็นอนุกรม

การทำให้คลาสเป็นอนุกรมใน Java เกี่ยวข้องกับการส่งข้อมูลทั้งหมดไปยังไฟล์ภายนอกหรือฐานข้อมูลผ่านทางสตรีม เราสามารถจำกัดข้อมูลที่จะถูกซีเรียลไลซ์ได้ทุกเมื่อที่ต้องการ มีสองวิธีในการทำเช่นนี้:
  • พารามิเตอร์คลาสแต่ละรายการที่ประกาศเป็นแบบชั่วคราวจะไม่ถูกทำให้เป็นอนุกรม (โดยค่าเริ่มต้น พารามิเตอร์ของคลาสทั้งหมดจะถูกทำให้เป็นอนุกรม)
  • หรือแต่ละพารามิเตอร์คลาสที่เราต้องการทำให้เป็นอนุกรมจะถูกทำเครื่องหมายด้วยแท็กExternalizable(โดยค่าเริ่มต้น ไม่มีพารามิเตอร์ใดที่ทำให้เป็นอนุกรม)
เขตข้อมูลจะไม่ถูกทำให้เป็นอนุกรมด้วยObjectOutputStreamเมื่อเรียกใช้บนออบเจ็กต์ หากเขตข้อมูลของออบเจ็กต์นั้นถูกทำเครื่องหมายว่าชั่วคราว ตัวอย่างเช่น: private transient String password. ในทางกลับกัน เพื่อประกาศข้อมูลของวัตถุอย่างชัดเจนว่าเป็นอนุกรมได้ เราต้องทำเครื่องหมายชั้นเรียนว่าเขียนและอ่านข้อมูลของวัตถุนั้น ExternalizablewriteExternalอย่างชัดเจนreadExteranl

บทสรุป

คุณลักษณะของการทำให้เป็นอนุกรมของอ็อบเจ็กต์นั้นใช้ในระบบแบบกระจายจำนวนมากเพื่อเป็นวิธีการถ่ายโอนข้อมูล แต่การทำให้เป็นอนุกรมจะเปิดเผยรายละเอียดที่ซ่อนอยู่ ซึ่งทำลายความถูกต้องของประเภทข้อมูลนามธรรม ซึ่งจะทำลายการห่อหุ้ม ในเวลาเดียวกัน เป็นเรื่องดีที่ทราบว่าข้อมูลของออบเจ็กต์ซีเรียลไลซ์นั้นเป็นข้อมูลเดียวกับที่อยู่ในออบเจ็กต์ดั้งเดิม นี่เป็นโอกาสอันดีในการใช้อินเทอร์เฟซObjectInputValidationและแทนที่เมธอดvalidateObject()แม้ว่าจะใช้โค้ดหลายบรรทัดก็ตาม หากไม่พบวัตถุ เราก็สามารถโยนข้อยกเว้นได้อย่างInvalidObjectExceptionเหมาะสม บทความต้นฉบับ: วิธีการทำงานของการทำให้เป็นอนุกรมใน Java
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION