読み込み中...コンピュータプログラミングにおいて、シリアライズ、もしくはシリアル化 (serialize) という用語は、次のような異なる2つの意味を有する。
#ある一つの資源を、複数の主体が利用しようとするときに、それを調整して、一つの時点では一つの主体だけがそれを利用するようにすること。この意味では逐次化という訳語が用いられる。対義語は並列化である。#ある環境に存在しているオブジェクトをバイト列やXMLフォーマットに変換すること。この意味では直列化という訳語が用いられる。同義語にがある。対義語は直列化復元ないしデシリアライズである。
シリアライズの名詞形はシリアライゼーション (serialization)である。
第一の意味の逐次化(ちくじか)は、主としてマルチスレッドプログラミングにおいて使われる用語で、この場合、ある資源が複数のスレッドから同時にアクセスを受け付けられるようになっていないとき、つまりマルチスレッド対応でないときに、マルチスレッド環境からもその資源を利用できるようにするために、同時のアクセス要求が起こったときには、それぞれのスレッドが順番にその資源を利用するように調整することをいう。一般には、これはその資源をロックできたひとつのスレッドのみがその資源の利用権を得、ロック中には他のスレッドはその資源をロックできない機構(排他制御)を用いるか、要求をキューに入れ、順次取り出して処理することにより実現される。
第二の意味の直列化(ちょくれつか)は、オブジェクト指向プログラミングにおいて使われる用語で、ある環境において存在しているオブジェクトを、バイト列やXMLフォーマットに変換することをいう。より具体的には、そのオブジェクトの状態を表す変数(フィールド)と、場合によってはオブジェクトの種類(クラス)を表すなんらかの識別子を、ファイル化できるようなバイト列やXMLフォーマットの形に書き出すことをいう。これにより、オブジェクトの表すデータを、ファイルとしてセーブしたり、ネットワークで送信したりすることができるようになる。このようにして得られたバイト列やXMLフォーマットは、直列化復元ないしデシリアライズによって、元のオブジェクトに復元される。
また、オブジェクトを直列化してファイルなどの永続記憶に保存することを永続化という。
Javaのシリアライズは直列化(第二の意味)で用いられる。
このシリアライズは、デザインパターンのひとつMemento パターンによる状態のスナップショット取得のほかJava RMIでネットワーク越しの外部メソッド呼び出しを行うときなどに使われている。
シリアライズは、SFなどに登場する転送装置に喩えられることがある。物質を一旦量子に変換してから遠隔地に転送し再び物質に戻すというテレポーテーションがシリアライズに似ていることからそう喩えられた。これはまさに、他のネットワーク上にあるシリアライズされたオブジェクトをファイルとしてリモートから転送してからデシリアライズして外部メソッドを自分のネットワーク上で呼び出すために利用されるJava RMIの動作原理にも似ている。
Java言語では直列化したいクラスにまたはインタフェースを実装することで、そのクラスのオブジェクトは直列化できるクラスを作ることができる。これらのインタフェースのうち、はマーカーインタフェースと呼ばれる、メソッド宣言がないものである。
を実装しているクラスのフィールドは、transient, static指定が無い限り、自動的にシリアライズによる保存対象にされる。を実装しているクラスでは、 , メソッドをオーバーライドして手動で保存したいフィールドを指定する必要がある。
のように、ストリーム固有識別子を宣言することにより、クラスの実装が変わった場合でも、同一のストリーム固有識別子を持つクラスは、互換性があることを意味する。ストリーム固有識別子を明示的に宣言していない時は、バイトストリームのシグニチャー(SHA-1)から自動生成される。
これらのオブジェクトをやによりファイルなどに出力する。
import java.io.FileOutputStream; import java.io.OutputStream; import java.io.ObjectOutputStream; //... SerializableObject object = new SerializableObject(); OutputStream outputStream = new FileOutputStream("serializableObject.obj"); ObjectOutputStream objectOutputStream= new ObjectOutputStream(outputStream); objectOutputStream.writeObject(object);これらを再びオブジェクトに復元(デシリアライズ)するにはやを用いる。
Javaにはtransientというキーワードを用いて、オブジェクト内でシリアライズしたくないフィールドをシリアライズするときに除外することができる。これにより無駄な情報によってシリアライズされたファイルの肥大化を押さえ軽量化し、シリアライズ、デシリアライズを高速化することができる。
public class SerializableObject implements Serializable { private String name; //シリアライズするときに保存されるフィールド。 private transient int hashCode; //シリアライズするときに無視されるフィールド。 }
読み込み中...