Java 入門

ホーム > 基本的な I/O > オブジェクトのシリアライズとデシリアライズ

オブジェクトのシリアライズとデシリアライズ

ObjectInputStream と ObjectOutputStream を用いることによって、 Java オブジェクトをファイルに出力したり、ファイルからオブジェクトを元にもどしたりできます。

ハードディスクなどの記憶装置などにメモリ上のオブジェクトを記録することを永続化 (パーシスタント) といいますが、このときオブジェクトを記憶装置上のバイト列に表現することをシリアライズといい、 記憶装置からデータを読み込んで Java オブジェクトに復元することをデシリアライズといいます。

ちなみに RPC とかの話などでリモートマシン上(あるいは何らかのバウンダリを越えた場所)にデータを送るような話をするときはマーシャリングといいます。

サンプル用クラス - Company と Employee

このページでは Company と Employee というクラスのオブジェクトをシリアライズ、デシリアライズすることをためします。

最初にそれらの定義をみてください。サンプルなので非常に簡単ですね。

package com.keicode.java.test;

import java.io.Serializable;

@SuppressWarnings("serial")
public class Company implements Serializable {
  String name;
  int numberOfEmployee;
  
  public Company(String name, int numberOfEmployee){
    this.name = name;
    this.numberOfEmployee = numberOfEmployee;
  }
  
  public String getName(){
    return name;
  }
  
  public int getNumberOfEmployee(){
    return numberOfEmployee;
  }
  

}

Employee クラスはこちら。

package com.keicode.java.test;

import java.io.Serializable;

@SuppressWarnings("serial")
public class Employee implements Serializable {
  String name;
  String email;
  
  public Employee(String name, String email){
    this.name = name;
    this.email = email;
  }
  
  public String getName(){
    return name;
  }
  
  public String getEmail(){
    return email;
  }
}

ポイントは Serializable というインターフェイスを実装していることです。Serializable インターフェイスはメソッドを持たない、単なるマーカーです。

シリアライズ

ファイルにシリアライズするには ObjectOutputStream を使います。バイナリデータを書く要領です。

package com.keicode.java.test;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class StreamTest4 {
  public static void main(String[] args) {
    try {
      
      ObjectOutputStream objOutStream = 
        new ObjectOutputStream(
          new FileOutputStream("/home/keisukeo/tmp/obj.bin"));
      
      Company company = new Company("ABC Inc.", 30);
      Employee emp = new Employee("Keisuke", "keisuke@example.com");

      objOutStream.writeObject(company);
      objOutStream.writeObject(emp);
      
      objOutStream.close();
      
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

ここでは Company オブジェクト、Employee オブジェクトを順番にシリアライズしました。

デシリアライズ - ObjectInputStream

Company オブジェクト、Employee オブジェクトをファイルから読み込んで元にもどしてみましょう。つまりデシリアライズしてみましょう。

package com.keicode.java.test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;

public class StreamTest5 {

  public static void main(String[] args) {
    try {
      
      ObjectInputStream objInStream 
        = new ObjectInputStream(
          new FileInputStream("/home/keisukeo/tmp/obj.bin"));
      
      Company company = (Company) objInStream.readObject();
      Employee emp = (Employee) objInStream.readObject();
      
      objInStream.close();

      System.out.println(company.getName() + " - " 
        + company.getNumberOfEmployee());
      System.out.println(emp.getName() + " - " + emp.getEmail());
      
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    }
  }

}

シリアライズするときに、Company、Employee の順番だったので、読み込むときも同じ順番で読み込んでいます。

オブジェクトのシリアライズとデシリアライズ

確かにこのように元に戻せたことが確認できました。

ホーム > 基本的な I/O > オブジェクトのシリアライズとデシリアライズ