transientキーワードは、Javaでクラスのフィールドを示すために使用されます。このフィールドはシリアル化プロセスから除外される必要があります。つまり、これらのフィールドはオブジェクトがバイトストリームに保存される際に保存されません。
これは次のような場合に便利です:
使用例は以下の通りです:
import java.io.*; class User implements Serializable { private String username; private transient String password; // シリアル化されない public User(String username, String password) { this.username = username; this.password = password; } }
デシリアライズ後、passwordフィールドはnullの値を持ちます。
もしtransientフィールドがSerializableを実装するオブジェクトへの参照である場合、どうなりますか?
答え:フィールドはそれでもシリアル化されません。これはフィールドに関することであり、オブジェクトの型には関係ありません。オブジェクトがSerializableを実装していても、フィールドがtransientでマークされている場合、それはシリアル化されないことになります。
例:
class Credentials implements Serializable { String password; } class Account implements Serializable { transient Credentials credentials; }
credentialsフィールドは常にデシリアライズ後にnullになります。たとえCredentialsがシリアル化可能であってもです。
物語
インターネットバンキングで「ユーザーセッション」オブジェクトを設計する際に、認証セッションフィールドをtransientとして宣言し忘れたため、シリアル化されたオブジェクトが機密情報と共にファイルに記録されました。これにより、個人データが漏洩しました。
物語
ブローカサービスで、いくつかのキャッシュフィールドがデフォルトでシリアル化されていました。シリアル化された状態から復旧した後、アプリケーションはキャッシュから古いデータを使用し始め、実際の口座残高と表示されている残高の間に不一致が生じました。
物語
開発者はtransientフィールドを実装し、値がデシリアライズ後に自動的に埋められると仮定しました。カスタムreadObject/writeObject構造を実装しなかったため、このフィールドはnullのままで、プログラムはこのフィールドへの最初のアクセス時にクラッシュしました。