シリアライズとデシリアライズ:オブジェクトの永続化

docs

以前の記事で、Javaのクラスとオブジェクトについて学んだよね。クラスとオブジェクトの概念 – オブジェクト指向の入り口 | ToolDocs

今回は、せっかく作ったオブジェクトのデータを保存したり、後で使えるようにしたりする方法について見ていこう。これをオブジェクトの永続化って言うんだけど、その中心になるのがシリアライズデシリアライズだよ。

シリアライズって何?

シリアライズとは、Javaのオブジェクトをバイト列に変換すること。バイト列っていうのは、簡単に言うとコンピュータが理解できる0と1の並びのことだね。

なんでそんなことをするかっていうと、オブジェクトってそのままじゃファイルに書き込んだり、ネットワークで送ったりできないんだ。例えば、君が作ったゲームのセーブデータ(プレイヤーの持ち物とかHPとか)をファイルに保存したいとするよね。そのセーブデータをオブジェクトとして持っていたら、直接ファイルには書き込めない。そこで、シリアライズしてバイト列に変換することで、ファイルに保存したり、ネットワーク経由で他のコンピュータに送ったりできるようになるんだ。

シリアライズの例:ゲームのセーブデータ

例えば、こんなプレイヤーの情報を保存するクラスがあったとするよ。

Java

import java.io.Serializable; // これが重要!

class Player implements Serializable {
    String name;
    int level;
    int hp;

    public Player(String name, int level, int hp) {
        this.name = name;
        this.level = level;
        this.hp = hp;
    }

    @Override
    public String toString() {
        return "名前: " + name + ", レベル: " + level + ", HP: " + hp;
    }
}

ポイントは、Serializableインターフェースを実装していること。これを付けないとシリアライズできないから注意してね!

じゃあ、このPlayerオブジェクトをファイルに保存してみよう。

Java

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

public class SaveGame {
    public static void main(String[] args) {
        Player player = new Player("勇者タマ", 10, 100);

        try (FileOutputStream fos = new FileOutputStream("save.dat");
             ObjectOutputStream oos = new ObjectOutputStream(fos)) {

            oos.writeObject(player); // オブジェクトをバイト列に変換してファイルに書き込み!
            System.out.println("セーブデータが保存されました!");

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

このコードを実行すると、save.datというファイルが作成されて、その中にplayerオブジェクトの情報がバイト列として保存されるんだ。

デシリアライズって何?

デシリアライズは、シリアライズの逆。バイト列を元のJavaオブジェクトに戻すことだよ。保存したセーブデータを読み込んで、またゲームを再開するときに必要になる処理だね。

デシリアライズの例:セーブデータの読み込み

さっき保存したsave.datを読み込んで、Playerオブジェクトに戻してみよう。

Java

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

public class LoadGame {
    public static void main(String[] args) {
        Player player = null;

        try (FileInputStream fis = new FileInputStream("save.dat");
             ObjectInputStream ois = new ObjectInputStream(fis)) {

            player = (Player) ois.readObject(); // バイト列をオブジェクトに戻す!
            System.out.println("セーブデータをロードしました!");
            System.out.println(player);

        } catch (FileNotFoundException e) {
            System.out.println("セーブデータが見つかりません。");
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

このコードを実行すると、save.datからバイト列を読み込み、それが再びPlayerオブジェクトとして復元されて、プレイヤーの情報が表示されるはずだよ。

シリアライズとデシリアライズの注意点

  • Serializableインターフェースの実装: これを忘れるとNotSerializableExceptionが発生するよ。
  • バージョンの互換性: オブジェクトのクラス構造(フィールドの追加や削除など)を変更した場合、以前にシリアライズしたデータがデシリアライズできなくなることがあるんだ。これを解決するにはserialVersionUIDというものを使うんだけど、これはちょっと高度な話だから、まずは「構造を変えると読めなくなることがある」ってことだけ覚えておけば大丈夫だよ。
  • セキュリティ: シリアライズされたデータは改ざんされる可能性があるから、重要な情報を扱う場合は暗号化するなどの対策が必要になることもあるよ。

まとめ


今回は、Javaのオブジェクトをファイルに保存したり、読み込んだりするためのシリアライズデシリアライズについて学んだよ。

  • シリアライズ: オブジェクトをバイト列に変換すること。
  • デシリアライズ: バイト列を元のオブジェクトに戻すこと。
  • これらを使うには、クラスにSerializableインターフェースを実装する必要がある。

これで、君が作ったオブジェクトのデータを永続化(保存)して、後で再利用する方法がわかったはず!ゲームのセーブ機能や、設定の保存なんかにも使えるから、ぜひ試してみてね。 

コメント

タイトルとURLをコピーしました