Java
 Computer >> コンピューター >  >> プログラミング >> Java

なぜJavaのtransient変数はシリアライズされないのか?仕組みと使い方を解説

シリアライズとは何か

シリアライズ(直列化)とは、Javaオブジェクトをバイト列(バイトストリーム)の形式で永続化するプロセスです。このバイト列には、オブジェクトが保持するデータに加えて、オブジェクトの型や、その中に格納されているデータの型に関する情報も含まれます。

シリアライズは、Javaオブジェクトの値や状態バイト列へ変換する処理であり、これによってオブジェクトをネットワーク経由で送信したり、ファイルなどに保存したりすることが可能になります。

一方、デシリアライズ(逆直列化)は、その逆の処理であり、バイトコードを対応するJavaオブジェクトへと復元する変換を指します。

transient変数とは

transient修飾子が付いた変数は、シリアライズの対象から除外される特別なメンバー変数です。つまり、オブジェクトをシリアライズする際に、transient変数の値はバイト列に書き込まれません。

そのため、デシリアライズを行ってオブジェクトを復元したときには、transient変数にはデータ型ごとのデフォルト値(intなら0、参照型ならnullなど)が設定されます。

パスワードや認証情報など、セキュリティ上の理由から永続化したくないデータや、一時的な計算結果など保存する必要がないフィールドに対して、transientキーワードを使用するのが一般的です。

構文

private transient <メンバー変数>;

サンプルコード

以下の例では、EmpInfoクラスのageフィールドにtransientを指定しています。オブジェクトをファイルに保存して再度読み込むと、ageだけがデフォルト値の0になっていることが確認できます。

import java.io.*;

class EmpInfo implements Serializable {
    String name;
    private transient int age;
    String occupation;

    public EmpInfo(String name, int age, String occupation) {
        this.name = name;
        this.age = age;
        this.occupation = occupation;
    }

    public String toString() {
        StringBuffer sb = new StringBuffer();
        sb.append("Name:" + "\n");
        sb.append(this.name + "\n");
        sb.append("Age:" + "\n");
        sb.append(this.age + "\n");
        sb.append("Occupation:" + "\n");
        sb.append(this.occupation);
        return sb.toString();
    }
}

// メインクラス
public class TransientVarTest {
    public static void main(String args[]) throws Exception {
        EmpInfo empInfo = new EmpInfo("Adithya", 30, "Java Developer");

        // オブジェクトをファイルにシリアライズ
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("empInfo"));
        oos.writeObject(empInfo);
        oos.close();

        // ファイルからオブジェクトをデシリアライズ
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("empInfo"));
        EmpInfo empInfo1 = (EmpInfo) ois.readObject();
        System.out.println(empInfo1);
    }
}

実行結果

Name:
Adithya
Age:
0
Occupation:
Java Developer

実行結果のポイント

出力を見ると、シリアライズ前に設定した年齢「30」ではなく、「0」が出力されています。これは、ageフィールドがtransientとして宣言されていたため、シリアライズの対象から除外され、デシリアライズ時にint型のデフォルト値である0が代入されたためです。

このように、transientキーワードを使うことで、機密性の高い情報や保存不要なデータを意図的にシリアライズの対象外とし、安全かつ効率的なオブジェクトの永続化を実現できます。

  1. Yahoo!大規模情報漏洩の影響は?セキュリティ重視のProtonMailを試してみよう

    Yahoo!が大規模なセキュリティ侵害を公式に認めました。このニュースを耳にしていない人はほとんどいないでしょう。3,700万以上のアカウントが流出したAshley Madisonのハッキング事件に代表されるように、近年こうした情報漏洩はもはや珍しい出来事ではありません。 しかし、Yahoo!の漏洩事件はAshley Madisonをはるかに上回る規模で、5億以上のアカウントが侵害されたことが確認されています。これを機に、ProtonMailのようなより安全な新しいメールサービスへの乗り換えを検討してみてはいかがでしょうか。 ProtonMailとは? ProtonMailは、暗号化されたメー

  2. Windows 10テクニカルプレビューをメインOSにすべきではない理由

    Windows 10テクニカルプレビューは今月初旬に公開されました。好意的なレビューを受けて、一部のユーザーはメインで使っているWindows 7や8をWindows 10にアップグレードしました。しかし、テクニカルプレビューがすべてのキー入力を記録しているという報道が浮上すると、無防備なユーザーは衝撃を受けたのです。テクニカルプレビューとは何かを理解していれば、決して驚くようなことではありません。本記事では、Windows 10テクニカルプレビューを例に、ソフトウェアの早期バージョンをどのように扱うべきか、そしてそれをメイン環境にするのがなぜ悪い考えなのかを解説します。テクニカルプレビューと