2

最終フィールドを遅延してインスタンス化することは可能ですか?

次のコードはコンパイルされません。

public class Test{
    private final Connection conn;

    public Connection getConnection(){
        if(conn==null){
            conn = new Connection();
        }
        return conn;
    }
}

代替手段はありますか?

4

5 に答える 5

8

いいえ。 final フィールドのポイントは、構築中に一度設定され、その後変更されることはないということです。コンパイラまたは VM は、あなたの場合に役立つことをどのように知ることができconnますか? そのプロパティだけがそれを設定でき、他のメソッドでは設定できないことをどのように知ることができますか?

おそらく、セマンティクスをどのようにしたいのかを説明していただければ、別の方法を思い付くことができます。値を取得する方法を表す「プロバイダー」インターフェースを作成しMemoizingProviderてから、別のプロバイダーにプロキシする可能性がありますが、それ以外の場合は値をキャッシュするのは一度だけです。キャッシュされた値の final フィールドを持つこともできませんが、少なくとも 1 か所にしかありません。

于 2009-03-23T09:38:47.673 に答える
3

Memoisation(Callablesを使用)を使用してそれを行う1つの方法を次に示します。

クラスメモ:

public class Memo<T> {
    private T result;
    private final Callable<T> callable;

    private boolean established;

    public Memo(final Callable<T> callable) {
        this.callable = callable;
    }

    public T get() {
        if (!established) {
            try {
                result = callable.call();
                established = true;
            }
            catch (Exception e) {
                throw new RuntimeException("Failed to get value of memo", e);
            }
        }
        return result;
    }
}

これで、最終接続を作成できます。

private final Memo<Connection> conn = new Memo<Connection>(
    new Callable<Connection>() {
    public Connection call() throws Exception {
        return new Connection();
    }
});

public Connection getConnection() {
    return conn.get();
}

ソース

于 2009-03-23T16:01:45.867 に答える