それで..従来のメソッドを使用してシリアル化したいクラスがあります(私たちは を使用します
Serializable
)
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
それらの。私たちは、「どうぞ、デシリアライズします。できます。バージョンは同じです」と言いました。
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;
}
それらの。serialVersionUID
Java には、そのアルゴリズム (非常に複雑なアルゴリズム) に基づいた独自の計算を実行させません。これで、クラスが変更されるたびに次のこと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;
}
クールです。すべてが引き続き機能します。ということで、最初の記事を書き終えました。このすべてをコメントに書きたかったのですが、記号を読み込むことができませんでした。冷静な批判とコメントは受け入れます 追伸、これらの楽しいことをするきっかけを与えてくれた著者に感謝します。おそらく、これが彼らの学び方です:) 皆さん、頑張ってください:)
GO TO FULL VERSION