JavaRush /จาวาบล็อก /Random-TH /เพื่อตอบสนองต่อบทความ "เหตุใดจึงต้องใช้ SerialVersionUID ...
Сергей
ระดับ
Киев

เพื่อตอบสนองต่อบทความ "เหตุใดจึงต้องใช้ SerialVersionUID ภายในคลาส Serializable ใน Java"

เผยแพร่ในกลุ่ม
ดังนั้น.. เรามีคลาสที่เราต้องการทำให้เป็นอนุกรมโดยใช้วิธีทั่วไป (เราใช้Serializable) เพื่อตอบสนองต่อบทความ "เหตุใดจึงต้องใช้ SerialVersionUID ภายในคลาส Serializable ใน Java" - 1
package Serialization;

import java.io.Serializable;

public class SerializableClass implements Serializable {
    private String name;
    private int number;
 }
เรากำลังเขียนใบสมัครทดสอบ ฉันจะบอกทันทีว่าเป้าหมายของฉันคือการแสดงserialVersionUIDอะไร
package Serialization;

import java.io.*;

public class MainSerializable {
    final static String FILE_NAME = "c:\\File.dat";

    public static void serialize(Object object) throws IOException {
        FileOutputStream fileOutputStream = new FileOutputStream(FILE_NAME);
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);

        objectOutputStream.writeObject(object);

        fileOutputStream.close();
        objectOutputStream.close();
    }

    public static Object deserialize() throws IOException, ClassNotFoundException {
        FileInputStream fileInputStream = new FileInputStream(FILE_NAME);
        ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);

        Object object = objectInputStream.readObject();

        objectInputStream.close();

        return object;
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        SerializableClass serializableClass = new SerializableClass();

        serialize(serializableClass);

        SerializableClass newObject = (SerializableClass) deserialize();
    }
}
ทุกอย่างทำงานได้ดีมาก คลาสถูกทำให้เป็นอนุกรมเป็นFILE_NAME = "c:\\File.dat"ไฟล์ เริ่มมืดแล้ว... :) ลืมเพิ่มฟิลด์ในชั้นเรียน เพิ่ม:
public class SerializableClass implements Serializable {
    private String name;
    private int number;
    private String FirstName;   // +
    private String LastName;    // +
 }
ดูเหมือนทุกอย่างจะเรียบร้อยดี.. ทุกอย่างคอมไพล์แล้ว.. ดังนั้นเราจึงรันมันmainทำการดีซีเรียลไลซ์คลาสSerializableClassจากไฟล์ " c:\\File.dat":
public static void main(String[] args) throws IOException, ClassNotFoundException {
    SerializableClass newObject = (SerializableClass) deserialize();
}
อ้าว...จะทำยังไง...
Exception in thread "main" java.io.InvalidClassException: Serialization.SerializableClass; local class incompatible: stream classdesc serialVersionUID = 8129437039424566964, local class serialVersionUID = -8271479231760195917
	at java.base/java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:689)
	at java.base/java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1903)
	at java.base/java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1772)
	at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2060)
	at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1594)
	at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:430)
	at Serialization.MainSerializable.deserialize(MainSerializable.java:22)
	at Serialization.MainSerializable.main(MainSerializable.java:30)
โดยทั่วไปแล้วทุกอย่างยุติธรรม คลาสมีการเปลี่ยนแปลงและ = serialVersionUIDและ-8271479231760195917ทำให้เป็นอนุกรมในไฟล์serialVersionUID= 8129437039424566964จะทำอย่างไรตอนนี้จะทำอย่างไร? จะสร้างอินสแตนซ์ได้อย่างไร? มีทางออก. เราจำเป็นต้องประกาศในคลาสของเรา: static final long serialVersionUIDซึ่งเท่ากับserialVersionUIDคลาส greyed out :) ในไฟล์ เหล่านั้น. เราบอกว่า เอาเลย ฉันจะดีซีเรียลไลซ์.. คุณทำได้.. เวอร์ชันของคุณเหมือนกัน:
package Serialization;

import java.io.Serializable;

public class SerializableClass implements Serializable {
    static final long serialVersionUID = 8129437039424566964L;

    private String name;
    private int number;
    private String FirstName;   // +
    private String LastName;    // +
}
เราเปิดตัว... และ.. ทุกอย่างใช้งานได้ ตามที่ฉันเข้าใจ ข้อผิดพลาดนี้สามารถหลีกเลี่ยงได้หากคลาสได้ประกาศล่วงหน้า:
public class SerializableClass implements Serializable {
    static final long serialVersionUID = 1L;

    private String name;
    private int number;
}
เหล่านั้น. เราไม่อนุญาตให้ Java ทำการคำนวณของตัวเองserialVersionUIDตามอัลกอริธึมของมัน (อัลกอริธึมที่ค่อนข้างซับซ้อน) ตอนนี้เมื่อใดก็ตามที่คลาสมีการเปลี่ยนแปลง เราserialVersionUID = 1L จะตรวจสอบ:
public static void main(String[] args) throws IOException, ClassNotFoundException {
    SerializableClass serializableClass = new SerializableClass();

    serialize(serializableClass);

    SerializableClass newObject = (SerializableClass) deserialize();
}
มันได้ผล.. และตอนนี้เช่นนี้:
public class SerializableClass implements Serializable {
    static final long serialVersionUID = 1L;

    //private String name;
    //private int number;
}
ใช่..แล้วไง?
public class SerializableClass implements Serializable {
    static final long serialVersionUID = 1L;
    public int A;
    protected String value;
    //private String name;
    //private int number;
}
เจ๋ง..ทุกอย่างยังคงทำงานต่อไป ดังนั้นฉันจึงเขียนบทความแรกของฉันเสร็จ ฉันต้องการใส่ทั้งหมดนี้ในความคิดเห็น แต่ฉันไม่สามารถอ่านสัญลักษณ์ได้ ฉันจะยอมรับคำวิจารณ์และความคิดเห็นอย่างมีสติ ป.ล. ขอบคุณผู้เขียนที่เป็นแรงบันดาลใจให้ฉันทำสิ่งที่น่าพอใจเหล่านี้.. อาจเป็นวิธีที่พวกเขาเรียนรู้ :) ขอให้ทุกคนโชคดี :)
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION