logo

Java でのシリアル化と逆シリアル化の例

シリアル化は、オブジェクトの状態をバイト ストリームに変換するメカニズムです。逆シリアル化は、バイト ストリームを使用してメモリ内に実際の Java オブジェクトを再作成する逆のプロセスです。このメカニズムはオブジェクトを永続化するために使用されます。 シリアライズ-デシリアライズ-Java
作成されるバイト ストリームはプラットフォームに依存しません。したがって、あるプラットフォームでシリアル化されたオブジェクトは、別のプラットフォームでは逆シリアル化できます。 Java オブジェクトをシリアル化可能にするには、 java.io.Serializable インターフェース。 ObjectOutputStream クラスには以下が含まれます writeObject() オブジェクトをシリアル化するメソッド。

public final void writeObject(Object obj)  throws IOException>

ObjectInputStream クラスには以下が含まれます readObject() オブジェクトを逆シリアル化するメソッド。



public final Object readObject()  throws IOException,  ClassNotFoundException>

シリアル化のメリット

  1. オブジェクトの状態を保存/永続化します。
  2. オブジェクトをネットワーク上で移動させること。

を実装しているクラスのオブジェクトのみをシリアル化できます。 java.io.Serializable インターフェース。シリアライズ可能とは、 マーカーインターフェイス (データメンバーとメソッドはありません)。これは、Java クラスのオブジェクトが特定の機能を取得できるように、Java クラスをマークするために使用されます。マーカー インターフェイスの他の例は次のとおりです。 - クローン可能およびリモート。



留意すべき点

1. 親クラスが Serializable インターフェイスを実装している場合、子クラスはそれを実装する必要はありませんが、その逆は当てはまりません。
2. 非静的データ メンバーのみがシリアル化プロセスを通じて保存されます。
3. 静的データ メンバーと一時データ メンバーは、シリアル化プロセスでは保存されません。したがって、非静的データ メンバーの値を保存したくない場合は、それを一時的なものにします。
4. オブジェクトが逆シリアル化されるときに、オブジェクトのコンストラクターが呼び出されることはありません。
5. 関連オブジェクトは Serializable インターフェイスを実装している必要があります。例 :

class A implements Serializable{  // B also implements Serializable // interface. B ob=new B();  }>

シリアルバージョンUID シリアル化ランタイムは、SerialVersionUID と呼ばれる各シリアル化可能クラスにバージョン番号を関連付けます。これは、シリアル化されたオブジェクトの送信者と受信者が、シリアル化に関して互換性のあるそのオブジェクトのクラスを読み込んでいることを検証するために、逆シリアル化中に使用されます。受信者が、対応する送信者のクラスの UID とは異なる UID を持つオブジェクトのクラスをロードした場合、逆シリアル化の結果、 無効なクラス例外



Serializable クラスは、フィールド名を宣言することで独自の UID を明示的に宣言できます。これは、static、final、long 型である必要があります。つまり、ANY-ACCESS-MODIFIER staticfinallongserialVersionUID=42L;シリアル化可能クラスが明示的にserialVersionUIDを宣言していない場合、Javaオブジェクトシリアル化仕様で説明されているように、シリアル化ランタイムはクラスのさまざまな側面に基づいてそのクラスのデフォルトのUIDを計算します。ただし、すべてのシリアル化可能なクラスで、serialVersionUID 値を明示的に宣言することを強くお勧めします。これは、その計算がコンパイラの実装によって異なる可能性のあるクラスの詳細に非常に敏感であり、クラスの変更や異なる ID の使用がシリアル化されたデータに影響を与える可能性があるためです。また、継承されたメンバーとしては役に立たないため、UID にはプライベート修飾子を使用することをお勧めします。 シリアルバー Serialver は JDK に付属するツールです。 JavaクラスのserialVersionUID番号を取得するために使用されます。

次のコマンドを実行して、serialVersionUID を取得できます。serialver [-classpath classpath] [-show] [classname…] 例 1:

ジャワ


インスタンスの



// Java code for serialization and deserialization> // of a Java object> import> java.io.*;> class> Demo>implements> java.io.Serializable> {> >public> int> a;> >public> String b;> >// Default constructor> >public> Demo(>int> a, String b)> >{> >this>.a = a;> >this>.b = b;> >}> }> class> Test> {> >public> static> void> main(String[] args)> >{> >Demo object =>new> Demo(>1>, 'geeksforgeeks');> >String filename = 'file.ser';> > >// Serialization> >try> >{> >//Saving of object in a file> >FileOutputStream file =>new> FileOutputStream(filename);> >ObjectOutputStream out =>new> ObjectOutputStream(file);> > >// Method for serialization of object> >out.writeObject(object);> > >out.close();> >file.close();> > >System.out.println('Object has been serialized');> >}> > >catch>(IOException ex)> >{> >System.out.println('IOException is caught');> >}> >Demo object1 =>null>;> >// Deserialization> >try> >{> >// Reading the object from a file> >FileInputStream file =>new> FileInputStream(filename);> >ObjectInputStream in =>new> ObjectInputStream(file);> > >// Method for deserialization of object> >object1 = (Demo)in.readObject();> > >in.close();> >file.close();> > >System.out.println('Object has been deserialized ');> >System.out.println('a = ' + object1.a);> >System.out.println('b = ' + object1.b);> >}> > >catch>(IOException ex)> >{> >System.out.println('IOException is caught');> >}> > >catch>(ClassNotFoundException ex)> >{> >System.out.println('ClassNotFoundException is caught');> >}> >}> }>

>

>

出力:

Object has been serialized Object has been deserialized  a = 1 b = geeksforgeeks>

例 2:

ジャワ




C言語の構造体の配列

// Java code for serialization and deserialization> // of a Java object> import> java.io.*;> class> Emp>implements> Serializable {> private> static> final> long> serialversionUID => >129348938L;> >transient> int> a;> >static> int> b;> >String name;> >int> age;> >// Default constructor> public> Emp(String name,>int> age,>int> a,>int> b)> >{> >this>.name = name;> >this>.age = age;> >this>.a = a;> >this>.b = b;> >}> }> public> class> SerialExample {> public> static> void> printdata(Emp object1)> >{> >System.out.println('name = ' + object1.name);> >System.out.println('age = ' + object1.age);> >System.out.println('a = ' + object1.a);> >System.out.println('b = ' + object1.b);> >}> public> static> void> main(String[] args)> >{> >Emp object =>new> Emp('ab',>20>,>2>,>1000>);> >String filename = 'shubham.txt';> >// Serialization> >try> {> >// Saving of object in a file> >FileOutputStream file =>new> FileOutputStream> >(filename);> >ObjectOutputStream out =>new> ObjectOutputStream> >(file);> >// Method for serialization of object> >out.writeObject(object);> >out.close();> >file.close();> >System.out.println('Object has been serialized '> >+ 'Data before Deserialization.');> >printdata(object);> >// value of static variable changed> >object.b =>2000>;> >}> >catch> (IOException ex) {> >System.out.println('IOException is caught');> >}> >object =>null>;> >// Deserialization> >try> {> >// Reading the object from a file> >FileInputStream file =>new> FileInputStream> >(filename);> >ObjectInputStream in =>new> ObjectInputStream> >(file);> >// Method for deserialization of object> >object = (Emp)in.readObject();> >in.close();> >file.close();> >System.out.println('Object has been deserialized '> >+ 'Data after Deserialization.');> >printdata(object);> >// System.out.println('z = ' + object1.z);> >}> >catch> (IOException ex) {> >System.out.println('IOException is caught');> >}> >catch> (ClassNotFoundException ex) {> >System.out.println('ClassNotFoundException' +> >' is caught');> >}> >}> }>

>

>

出力:

Object has been serialized Data before Deserialization. name = ab age = 20 a = 2 b = 1000 Object has been deserialized Data after Deserialization. name = ab age = 20 a = 0 b = 2000>

出力の説明: オブジェクトの逆シリアル化中に、a と b の値が変更されたことが分かりました。その理由は、a が一時的としてマークされ、b が静的であるためです。

の場合には 一時的な変数:- transient キーワードで定義された変数は、シリアル化プロセス中にシリアル化されません。この変数は、逆シリアル化中にデフォルト値で初期化されます。 (例: オブジェクトの場合は null、int の場合は 0)。

の場合には 静的変数:- static キーワードで定義された変数は、シリアル化プロセス中にシリアル化されません。この変数は、逆シリアル化中にクラスで定義された現在の値でロードされます。

一時的なものと最終的なもの:
最後の 変数は、その値によって直接シリアル化に参加します。
したがって、final 変数を一時変数として宣言しても意味がありません。
//コンパイラは最終変数に値を代入します

例:

final int x= 10; int y = 20; System.out.println(x);// compiler will replace this as System.out.println(10)->x が最終なので 10 です。 System.out.println(y);//20>>' 

例 3:

ジャワ




//java code for final with transient> import> java.io.*;> class> Dog>implements> Serializable{> >int> i=>10>;> >transient> final> int> j=>20>;> }> class> GFG {> >public> static> void> main (String[] args)>throws> IOException,ClassNotFoundException> >{> >Dog d1=>new> Dog();> >//Serialization started> >System.out.println(>'serialization started'>);> >FileOutputStream fos=>new> FileOutputStream(>'abc.ser'>);> >ObjectOutputStream oos=>new> ObjectOutputStream(fos);> >oos.writeObject(d1);> >System.out.println(>'Serialization ended'>);> > >//Deserialization started> >System.out.println(>'Deserialization started'>);> >FileInputStream fis=>new> FileInputStream(>'abc.ser'>);> >ObjectInputStream ois=>new> ObjectInputStream(fis);> >Dog d2=(Dog) ois.readObject();> >System.out.println(>'Deserialization ended'>);> >System.out.println(>'Dog object data'>);> >//final result> >System.out.println(d2.i+>' '> +d2.j);> >}> }>

>

出力

serialization started Serialization ended Deserialization started Deserialization ended Dog object data 10 20>