JavaRush /Blog Java /Random-PL /W odpowiedzi na artykuł „Po co używać SerialVersionUID w ...
Сергей
Poziom 31
Киев

W odpowiedzi na artykuł „Po co używać SerialVersionUID w klasie Serializable w Javie”

Opublikowano w grupie Random-PL
A więc... Mamy klasę, którą chcemy serializować przy użyciu konwencjonalnych metod (używamy Serializable) W odpowiedzi na artykuł „Po co używać SerialVersionUID wewnątrz klasy Serializable w Javie” – 1
package Serialization;

import java.io.Serializable;

public class SerializableClass implements Serializable {
    private String name;
    private int number;
 }
Piszemy aplikację testową. Od razu powiem, że moim celem jest pokazanie czego 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();
    }
}
Wszystko działa świetnie. Klasa jest serializowana do pliku FILE_NAME = "c:\\File.dat". Robiło się już ciemno... :) Zapomniałem dodać pola do klasy. Dodać:
public class SerializableClass implements Serializable {
    private String name;
    private int number;
    private String FirstName;   // +
    private String LastName;    // +
 }
Wszystko wydaje się być w porządku.. wszystko się kompiluje.. Więc uruchamiamy to main, deserializujemy klasę SerializableClassz pliku „ c:\\File.dat”:
public static void main(String[] args) throws IOException, ClassNotFoundException {
    SerializableClass newObject = (SerializableClass) deserialize();
}
Och... Co robić...
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)
Generalnie wszystko jest sprawiedliwe. Klasa została zmieniona, a jej serialVersionUID= -8271479231760195917i serializowana w pliku serialVersionUID= 8129437039424566964. Co teraz zrobić, co zrobić? Jak stworzyć instancję? Jest wyjście. Musimy zadeklarować w naszej klasie: static final long serialVersionUID, która jest równa serialVersionUIDwyszarzonej klasie :) w pliku. Te. powiedzieliśmy: śmiało, deserializuję… możesz… twoje wersje są takie same:
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;    // +
}
Uruchamiamy... I.. Wszystko działa.O ile rozumiem, tego błędu można było uniknąć, gdyby klasa wcześniej zadeklarowała:
public class SerializableClass implements Serializable {
    static final long serialVersionUID = 1L;

    private String name;
    private int number;
}
Te. nie pozwalamy Javie wykonywać własnych obliczeń serialVersionUIDw oparciu o jej algorytmy (dość złożone algorytmy). Teraz za każdym razem, gdy zmienia się klasa, sprawdzamy serialVersionUID = 1L :
public static void main(String[] args) throws IOException, ClassNotFoundException {
    SerializableClass serializableClass = new SerializableClass();

    serialize(serializableClass);

    SerializableClass newObject = (SerializableClass) deserialize();
}
Działa.. A teraz tak:
public class SerializableClass implements Serializable {
    static final long serialVersionUID = 1L;

    //private String name;
    //private int number;
}
Tak.. I tak?
public class SerializableClass implements Serializable {
    static final long serialVersionUID = 1L;
    public int A;
    protected String value;
    //private String name;
    //private int number;
}
Super.. wszystko nadal działa. Tak skończyłem mój pierwszy artykuł. Chciałem to wszystko umieścić w komentarzach, ale nie udało mi się przejść przez symbole. Przyjmę trzeźwą krytykę i uwagi PS Dziękuję autorce, która mnie zainspirowała do zrobienia tych pyszności.. Pewnie tak się uczą :) Powodzenia wszystkim :)
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION