ProgrammingJava開発者

Javaにおける`transient`キーワードはどのように機能しますか?オブジェクトのシリアル化時の目的と使用上の特徴について説明してください。

Hintsage AIアシスタントで面接を突破

答え

transientキーワードは、Javaでクラスのフィールドを示すために使用されます。このフィールドはシリアル化プロセスから除外される必要があります。つまり、これらのフィールドはオブジェクトがバイトストリームに保存される際に保存されません。

これは次のような場合に便利です:

  • フィールドが機密データ(例:パスワード)を含む場合
  • フィールドがデシリアライズ後に復元可能な場合
  • フィールドの状態がJVM特有であり、JVM間で渡す必要がない場合

使用例は以下の通りです:

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のままで、プログラムはこのフィールドへの最初のアクセス時にクラッシュしました。