4

transientプロパティに単純にラベルを付けてシリアル化を防ぐことができることを考えると、外部化の目的について考えていました。しかし、さらに調査した結果transient、実行時に何が必要かを判断する必要がある場合、このアプローチ (つまり、 としてラベルを付ける) は理想的ではない可能性があることがわかりました。理論的には、私には理にかなっています。ただし、実際には、Externalization が実行時にどのように使いやすいかはわかりません。つまり、クラスの定義中writeExternal()および定義中に、何が必要かどうかを決定する必要があります。readExternal()では、どのように実行時に使いやすいのでしょうか?

これを強調したドキュメントは次のとおりです。

Serializable インターフェースを実装することですべてが自動的に処理される場合、Externalizable インターフェースを実装してわざわざ 2 つのメソッドを定義する必要があるでしょうか? プロセスを完全に制御するだけです。わかりました...これを理解するためにサンプル例を見てみましょう。数百のフィールド (非一時的) を持つオブジェクトがあり、すべてではなく少数のフィールドのみを永続ストレージに格納したいとします。1 つの解決策は、他のすべてのフィールド (シリアル化するフィールドを除く) を一時的として宣言することであり、デフォルトのシリアル化プロセスが自動的にそれを処理します。しかし、これらのいくつかのフィールドが設計時に固定されず、代わりに実行時に条件付きで決定される場合はどうなるでしょうか。このような状況では、Externalizable インターフェイスを実装することがおそらくより良い解決策になるでしょう。

4

2 に答える 2

4
public class Foo implements Externalizable{
    private long userID;
    private String userName;
    private char[] userPassword;
    private int age;

    private boolean shouldSavePassword;

    public void setSavePassword(boolean shouldSavePassword){
        this.shouldSavePassword = shouldSavePassword;
    }

    void writeExternal(ObjectOutput out) throws IOException{
        out.writeObject(userID);
        out.writeObject(userName);
        out.writeObject(shouldSavePassword);

        if(shouldSavePassword){
            out.writeObject(userPassword);
        }

        out.writeObject(age);
    }

    void readExternal(ObjectInput in) throws IOException, ClassNotFoundException{
        userID = in.readLong();
        userName = (String) in.readObject();
        shouldSavePassword = readBoolean();

        if(shouldSavePassword){
            userPassword = (char[]) in.readObject();
        }

        age = in.readInt();
    }
}

userPasswordフィールドが のランタイム値でのみシリアル化されることに注意してくださいshouldSavePassword。フィールドを一時的であると宣言した場合、コンパイル時のプロパティをシリアル化するかどうかを決定し、実行時に変更することはできません (リフレクションを使用しない限り)。

また、Externalizable の柔軟性により、機密性の高いオブジェクトを必要に応じて暗号化して、独自のシリアライゼーション スキームを決定することもできます。

別のユースケースとして、信頼性を最大限に高めるために、クラスの最後に一方向ハッシュをアタッチするオプションが考えられます。フィールドは、ハッシュを保存するかどうかを決定できます (追加の計算であるため)。

肝心transientなのは、オブジェクトのシリアル化がどのように行われるかを実行時に制御することはできず、単にフィールドがシリアル化されるかどうかを (コンパイル時のパラメーターとして) 制御することです。


免責事項:上記の例は、パスワードを保存するためのひどいスキームです。本番アプリケーションには使用しないでください。プレーンテキストのパスワードは、bcrypt、PBKDF#2、scrypt などの PBPDF を通過した後に保存する必要があります。

于 2015-06-30T07:14:54.577 に答える