So.. We have a class that we want to serialize using conventional methods (we use
Serializable
)
package Serialization;
import java.io.Serializable;
public class SerializableClass implements Serializable {
private String name;
private int number;
}
We are writing a test application. I’ll say right away that my goal is to show what 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();
}
}
Everything works great. The class is serialized to a file FILE_NAME = "c:\\File.dat"
. It was getting dark... :) Forgot to add fields to the class. Add:
public class SerializableClass implements Serializable {
private String name;
private int number;
private String FirstName; // +
private String LastName; // +
}
Everything seems to be fine.. everything compiles.. So we run it main
, deserialize the class SerializableClass
from the file " c:\\File.dat
":
public static void main(String[] args) throws IOException, ClassNotFoundException {
SerializableClass newObject = (SerializableClass) deserialize();
}
Oh... What to do...
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)
In general, everything is fair. The class has changed and its serialVersionUID
= -8271479231760195917
, and serialized in the file serialVersionUID
= 8129437039424566964
. What to do now, what to do? How to create an instance? There is an exit. We need to declare in our class: static final long serialVersionUID
, which is equal to serialVersionUID
the grayed out :) class in the file. Those. we said, go ahead, I’ll deserialize.. you can.. your versions are the 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; // +
}
We launch... And.. Everything works. As I understand, this error could have been avoided if the class had declared in advance:
public class SerializableClass implements Serializable {
static final long serialVersionUID = 1L;
private String name;
private int number;
}
Those. we don't let Java do its own calculations serialVersionUID
based on its algorithms (quite complex algorithms). Now, whenever a class changes, we serialVersionUID = 1L
check:
public static void main(String[] args) throws IOException, ClassNotFoundException {
SerializableClass serializableClass = new SerializableClass();
serialize(serializableClass);
SerializableClass newObject = (SerializableClass) deserialize();
}
It works.. And now like this:
public class SerializableClass implements Serializable {
static final long serialVersionUID = 1L;
//private String name;
//private int number;
}
Yes.. And so?
public class SerializableClass implements Serializable {
static final long serialVersionUID = 1L;
public int A;
protected String value;
//private String name;
//private int number;
}
Cool.. everything continues to work. So I finished my first article. I wanted to put all this in the comments, but I couldn’t get through the symbols. I will accept sober criticism and comments PS Thanks to the author who inspired me to do these delights.. Probably, this is how they learn :) Good luck to everyone :)
GO TO FULL VERSION