JavaRush /Java Blog /Random-TW /回應《Why use SerialVersionUID inside the Serialized class i...
Сергей
等級 31
Киев

回應《Why use SerialVersionUID inside the Serialized class in Java》一文

在 Random-TW 群組發布
所以..我們有一個類,我們想使用常規方法序列化(我們使用Serializable回應文章“Why use SerialVersionUID inside the Serialized class in 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反序列化該類: SerializableClassc:\\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檔案中灰顯的:)類別。那些。我們說,繼續,我會反序列化.. 你可以.. 你的版本是相同的:
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;
}
那些。我們不讓JavaserialVersionUID根據其演算法(相當複雜的演算法)進行自己的計算。現在,每當類別發生變化時,我們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;
}
酷..一切都繼續進行。這樣我就完成了我的第一篇文章。我想把這些都寫在評論裡,但我無法通過符號。我會接受清醒的批評和評論 PS 感謝啟發我做這些快樂的作者。可能,這就是他們學習的方式:)祝大家好運:)
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION