ここでは、Preferences APIの設計に関するよくある質問をまとめてあります。
これは、非常によく使用されてきたPropertiesクラスを置き換える目的で設計されており、軽量性を維持しながら、様々な点を訂正しています。Propertiesを使用するときは、各プロパティ・ファイルのパス名を明示的に指定する必要がありますが、標準の場所や名前の規約はありません。プロパティ・ファイルは壊れやすくなっています。手動で編集できますが、不注意な編集によって簡単に破損します。文字列以外のデータ型のサポートは存在しません。Propertiesは、ファイル・システム以外の永続性メカニズムで簡単に使用することはできません。つまり、Propertiesの機能には拡張性がありません。
JNDIと同様に、永続的なキー/値データへのバックエンド中立的なアクセスを提供します。ただし、JNDIは、はるかに強力で重量です。JNDIは、強力な機能を必要とする企業アプリケーションに適しています。Preferences APIは、単純で、汎用的な、バックエンド中立性を持つ設定管理機能として設計されているため、Javaアプリケーションの動作をユーザーの要望に合わせて簡単に調整でき、実行をまたがって一部の状態を保持できます。
get
メソッドに対して呼出し側がデフォルトを渡す必要があるのはなぜですか。
これによって、アプリケーション作成者は強制的に相応のデフォルト値を提供することになり、リポジトリが利用できない場合でもアプリケーションは相応の実行機会を得ることになります。
BackingStoreException
をスローするべきかはどのようにして決定されたのですか。
セマンティックスが絶対的にバッキング・ストアとのやり取りを必要としているメソッドだけが、この例外をスローします。通常のアプリケーションでは、このようなメソッドを呼び出す必要はありません。このようなメソッドを呼び出さないかぎり、バッキング・ストアを利用できない場合でもアプリケーションは実行でき、それが設計の明示的な目標でした。
このAPIは基本的な永続データ・ストレージを提供しますが、それはデータベースの代替を意図したものではありません。このAPIを標準の設定/構成リポジトリ上に実装できることが重要で、そのほとんどはデータベースのような保証および機能を提供しません。このようなリポジトリは、このAPIが意図する目的を十分に満たしています。
Javaプログラミング言語では、大文字と小文字が区別されるStringキーが一般的です。具体的には、それらはPropertiesクラスによって提供されており、このAPIが置き換える予定です。大文字小文字の区別を要求する方法でPropertiesを使用する人は珍しくありません。たとえば、Javaパッケージ名(大文字小文字を区別)がキーとして使用されることがあります。この設計上の意思決定は、大文字小文字を区別するキーを使用するバッキング・ストア上にPreferencesを実装するシステム・プログラマの寿命を複雑にすると認識されていますが、これは受入れ可能な対価と考えられます。はるかに多くのプログラマがそれを実装するよりPreferences APIを使用するようになるでしょう。
このAPIは、かなり特定の目的のために設計されており、その目的のために最適化されています。ジェネリック型がないので(JSR-14を参照)、このAPIは典型的なユーザーにとって便利さに欠けます。Map APIに対して強制的に準拠される場合、コンパイル時型安全性が不足します。また、ほかのMap実装との相互運用性が要求されることは想定していません(この想定が間違っているとわかった場合には、アダプタ・クラスを実装することは簡単です)。Preferences APIは設計上、Mapによく似ているため、後者に習熟しているプログラマは前者を使用することは難しくないはずです。
それらのメソッドは、バッキング・ストアが利用できない場合でも、実行可能であることが望ましいです。それらが古い値を返す必要がある場合、これはできなくなります。さらに、このAPIが一部の一般的なバックエンド・データ・ストア上に実装されている場合は、パフォーマンスが低下します。
この機能は、エンタープライズ全体の設定管理を拡張可能かつコスト効率的にするためにエンタープライズ設定に必要ですが、自己管理される単一ユーザー設定では過剰です。
直列化されたオブジェクトは、やや壊れやすくなっています。そのようなプロパティを読み取るプログラムがそれを書き出すプログラムと異なる場合は、オブジェクトが正しくまたはまったく直列化復元されないことがあります。直列化されたオブジェクトをこのAPIを使用して保存することはできますが、推奨しておらず、便利なメソッドも提供していません。
Preferences
がインタフェースでなく、抽象クラスなのはなぜですか。
上位互換性のある方法で新しいメソッドを追加する機能が、Preferencesを「ミックスイン」として使用できないというデメリットを上回ると判断されました。つまり、任意のクラスをPreferencesオブジェクトとして使用することもできません。
システムおよびユーザー・プリファレンス・データは、実装ごとに異なるバッキング・ストアに永続的に保存されます。たとえば、フラット・ファイル、OS固有のレジストリ、ディレクトリ・サーバー、SQLデータベースなどのバッキング・ストアに格納されます。たとえば、Windowsシステムでは、データはWindowsレジストリに格納されます。
Linuxシステムでは、システム・プリファレンスは通常、ネットワーク・インストールのjava-home/.systemPrefs
に格納されるか、ローカル・インストールの/etc/.java/.systemPrefs
に格納されます。両方とも存在する場合は、/etc/.java/.systemPrefs
が優先されます。システム・プロパティjava.util.prefs.systemRoot
を設定して、システム・プリファレンスの場所をオーバーライドできます。ユーザー・プリファレンスは通常、user-home/.java/.userPrefs
に格納されています。システム・プロパティjava.util.prefs.userRoot
を設定して、ユーザー・プリファレンスの場所をオーバーライドできます。