Le serialVersionUID est fourni pour déterminer la compatibilité entre un objet désarticulé et la version actuelle de la classe. En tant que telle, elle n'est pas vraiment nécessaire dans la première version d'une classe, ou dans ce cas, dans une classe de base abstraite. Vous n'aurez jamais une instance de cette classe abstraite à sérialiser/désérialiser, donc elle n'a pas besoin d'un serialVersionUID.
(Bien sûr, cela génère un avertissement du compilateur, dont vous voulez vous débarrasser, n'est-ce pas ?)
Il s'avère que le commentaire de James est correct. Le serialVersionUID d'une classe de base abstraite fait se propagent aux sous-classes. Compte tenu de cela, vous faire avez besoin du serialVersionUID dans votre classe de base.
Le code à tester :
import java.io.Serializable;
public abstract class Base implements Serializable {
private int x = 0;
private int y = 0;
private static final long serialVersionUID = 1L;
public String toString()
{
return "Base X: " + x + ", Base Y: " + y;
}
}
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class Sub extends Base {
private int z = 0;
private static final long serialVersionUID = 1000L;
public String toString()
{
return super.toString() + ", Sub Z: " + z;
}
public static void main(String[] args)
{
Sub s1 = new Sub();
System.out.println( s1.toString() );
// Serialize the object and save it to a file
try {
FileOutputStream fout = new FileOutputStream("object.dat");
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject( s1 );
oos.close();
} catch (Exception e) {
e.printStackTrace();
}
Sub s2 = null;
// Load the file and deserialize the object
try {
FileInputStream fin = new FileInputStream("object.dat");
ObjectInputStream ois = new ObjectInputStream(fin);
s2 = (Sub) ois.readObject();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println( s2.toString() );
}
}
Exécutez le main in Sub une fois pour qu'il crée et enregistre un objet. Ensuite, changez le serialVersionUID dans la classe de base, commentez les lignes de main qui sauvegardent l'objet (pour qu'il ne le sauvegarde pas à nouveau, vous voulez juste charger l'ancien), et exécutez-le à nouveau. Il en résultera une exception
java.io.InvalidClassException: Base; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2
3 votes
Je commence toujours à écrire une réponse, puis je réalise que je ne sais pas vraiment, même si j'ai une intuition. +1 pour une question à laquelle je ne peux pas répondre.