Java では、serializable (シリアル化)を使用して作成したオブジェクトをバイトストリームに変換し,そのバイトストリームから再び元と同じ内容を持ったオブジェクトを再現することが可能です。例えば、とあるマシン上にてオブジェクトをシリアル化し、ネットワーク等を利用して、他のマシン上にオブジェクトの複製を作ることが出来ます。
以下が、serializable の記述形式になります。
アクセス修飾子 class クラス名 implements Serializable { 処理; }
以下は、「ObjectInputStream」クラスと「ObjectOutputStream」クラスを利用してシリアル化を行う簡単なプログラムの例です。
import java.io.*; public class SerializableTest_A implements Serializable { protected String file; protected String str_a; protected String str_b; protected String str_c; protected String str_d; protected String str_e; public static void main(String[] args) throws Exception { //シリアル化して書き出す FileOutputStream fs = new FileOutputStream("output"); ObjectOutputStream os = new ObjectOutputStream(fs); os.writeObject( new SerializableTest_A( "--SerializableTest_Aで生成--", "k「今日も出番なかったな」", "s「そうだね」", "k「なんかキャラ増え過ぎじゃない?」", "s「あ。それ言おうと思ってたよ」", "k,s「なんだかな〜・・・はぁ〜・・」")); os.close(); } //コンストラクタの生成 public SerializableTest_A( String file, String str_a, String str_b, String str_c, String str_d, String str_e) { this.file = file; this.str_a = str_a; this.str_b = str_b; this.str_c = str_c; this.str_d = str_d; this.str_e = str_e; } }
上記のプログラムを実行すると、オブジェクトをシリアル化することが出来ます。
そして、以下が上記で生成されたオブジェクトを元に生成することが出来るプログラムの簡単な例です。
import java.io.*; public class SerializableTest_B { public static void main(String[] args) throws Exception { //シリアル化ストリームを読み込んでオブジェクトを復元 FileInputStream fs = new FileInputStream("output"); ObjectInputStream os = new ObjectInputStream(fs); SerializableTest_A sa = (SerializableTest_A) (os.readObject()); System.out.println(sa.file); System.out.println(sa.str_a); System.out.println(sa.str_b); System.out.println(sa.str_c); System.out.println(sa.str_d); System.out.println(sa.str_e); } }
以下が、上記のプログラムの実行結果です。
--SerializableTest_Aで生成-- k「今日も出番なかったな」 s「そうだね」 k「なんかキャラ増え過ぎじゃない?」 s「あ。それ言おうと思ってたよ」 k,s「なんだかな〜・・・はぁ〜・・」
実行結果を見てもわかるように 「SerializableTest_A」で定義されていたものが、「SerializableTest_B」で使用出来ていることがわかります。
上記では、シリアル化について記述してきましたが、中にはシリアル化をしたくない変数がある場合もあります。そのような場合に使用されるのが、transient
です。transient を記述することによって指定された変数はシリアル化を防ぐことが出来ます。
以下がそのプログラムの例です。
import java.io.*; public class SerializableTest_A implements Serializable { protected String file; protected String str_a; protected String str_b; protected String str_c; protected String str_d; protected transient String str_e; public static void main(String[] args) throws Exception { //シリアル化して書き出す FileOutputStream fs = new FileOutputStream("output"); ObjectOutputStream os = new ObjectOutputStream(fs); os.writeObject( new SerializableTest_A( "--SerializableTest_Aで生成--", "k「今日も出番なかったな」", "s「そうだね」", "k「なんかキャラ増え過ぎじゃない?」", "s「あ。それ言おうと思ってたよ」", "k,s「なんだかな〜・・・はぁ〜・・」")); os.close(); } //コンストラクタの生成 public SerializableTest_A( String file, String str_a, String str_b, String str_c, String str_d, String str_e) { this.file = file; this.str_a = str_a; this.str_b = str_b; this.str_c = str_c; this.str_d = str_d; this.str_e = str_e; } }
以下が上記のプログラムを実行してから、「SerializableTest_B」クラスを実行した実行結果です。
--SerializableTest_Aで生成-- k「今日も出番なかったな」 s「そうだね」 k「なんかキャラ増え過ぎじゃない?」 s「あ。それ言おうと思ってたよ」 null
実行結果を見てもわかるように transient 指定した変数はシリアル化されていないことがわかります。