Java 11 Gold 取得に向けた学習記録
プロパティファイル
アプリケーションの設定情報を「外部ファイル」としてアプリケーションと分離させることで、コードの再コンパイル、アプリケーションの再ビルドをせずに挙動を変える手法がある。
このときの「外部ファイル」を プロパティファイル と言う。
プロパティファイルの実体は、キーバリュー形式で値を保持する単なる テキストファイル である。
キー=バリュー
拡張子は通常 .properties とすることが多く、settings.properties や config.properties というファイル名が多く使用される。
キーとバリューは以下のように = と : を使用して記述する。キーには . を使用することができる。
password=hello
database.password=world
database.username:suzuki
プロパティファイルを扱うためには Properties クラスか ResourceBundle クラスを利用する。
Properties
プロパティファイルを利用する際は java.util.Properties クラスを利用する。
load()
プロパティファイルを読み込む際は Properties クラスの load() メソッドを使用する。
load() メソッドには、文字データのストリームを扱う Reader インターフェース型を受け取るものと、バイナリデータのストリームを扱う InputStream インターフェース型を受け取るものがある。
public void load(Reader reader) throws IOException
public void load(InputStream inStream) throws IOException
config.properties をプロジェクトのルートディレクトリ直下に配置する。
a=hello
b:world
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Properties;
Properties properties = new Properties();
try (Reader reader = new FileReader("config.properties")) {
// ファイルの読み込み
properties.load(reader);
} catch (IOException e) {
}
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
Properties properties = new Properties();
try (InputStream input = new FileInputStream("config.properties")) {
// ファイルの読み込み
properties.load(input);
} catch (IOException e) {
}
get() / getProperty()
Properties オブジェクトから情報を取得する方法には、get() メソッドを使用する方法とgetProperty() メソッドを使用する方法の2通りがある。
| シグネチャ | 定義されているクラス | 引数の型 | 補足 |
|---|---|---|---|
V get(Object key) |
java.util.Hashtableから継承している |
Object型 |
デフォルト値の設定ができない。 |
public String getProperty(String key) |
java.lang.Properties |
String型 |
プロパティが存在しない場合のデフォルト値が設定できる。 プロパティの操作に特化している。 推奨 |
// キャストが必要
String a = (String) properties.get("a");
String b = (String) properties.get("b");
System.out.println(a);
System.out.println(b);
// >> hello
// >> world
String a = properties.getProperty("a");
String b = properties.getProperty("b");
String c = properties.getProperty("c", "default_value"); // デフォルト値の設定
System.out.println(a);
System.out.println(b);
System.out.println(c);
// >> hello
// >> world
// >> default_value
list()
取得するプロパティの一覧は list() メソッドによって出力することができる。
public void list(PrintStream out)
public void list(PrintWriter out)
properties.list(System.out);
// >> -- listing properties --
// >> a=hello
// >> b=world
ResourceBundle
プロパティファイルは java.util.ResourceBundle クラスを使用して扱うこともできる。
ResourceBundle クラスは ローカライズ(i18n)機能の一部であり、異なるロケール(地域や言語)に基づいた文字列やその他の リソースバンドル を管理するために利用される。
ファイル名は通常、基底名(baseName)に ロケール識別子(言語コード、国コード)を付けた形式になる。
ロケール識別子を付与しないプロパティファイルは、ロケールが見つからないときのデフォルトのプロパティファイルとして扱われる。
このようにロケールに合わせたプロパティファイルを複数用意しておき、リソースバンドルとして利用することで、設定を簡単にローカライズできるようになる。
MyResources.properties はクラスパスのルートディレクトリである src/main/resources/ に配置する。
a=hello
b:world
ロケール ja_JP 環境下では、 MyResources.properties ではなく MyResources_ja_JP.properties が読み込まれる。
a=ハロー
b:ワールド
ResourceBundle.getBundle()
リソースバンドルを取得するためには ResourceBundle.getBundle() メソッドを利用する。getBundle() メソッドは Properties クラスを利用した場合の load() メソッドに相当する。
引数 baseName にはファイル名ではなく 基底名 を指定する。
static ResourceBundle getBundle(String baseName)
static ResourceBundle getBundle(String baseName, Locale locale)
ResourceBundle bundle = ResourceBundle.getBundle("MyResources");
第二引数の locale を指定しない場合は、プラットフォームのデフォルトのロケールが使用される。つまり、下の2つのコードは同義ということになる。
ResourceBundle bundle = ResourceBundle.getBundle("MyResources");
ResourceBundle bundle = ResourceBundle.getBundle("MyResources", Locale.getDefault());
locale を指定した場合、特定のロケールに基づくバンドルを取得することができる。
getString()
getString() を使用することで、取得したバンドルからプロパティを取得することができる。
public final String getString(String key)
String a = bundle.getString("a");
String b = bundle.getString("b");
System.out.println(a);
System.out.println(b);
// >> hello
// >> world
プロパティファイルを複数用意しておけば、ロケールに基づくプロパティを取得することができる。
a=hello
b:world
a=ハロー
b:ワールド
ResourceBundle bundle = ResourceBundle.getBundle("MyResources");
ResourceBundle bundleJa = ResourceBundle.getBundle("MyResources", new Locale("ja", "JP"));
String a = bundle.getString("a");
String aJa = bundleJa.getString("a");
String b = bundle.getString("b");
String bJa = bundleJa.getString("b");
System.out.println(a);
System.out.println(aJa);
System.out.println(b);
System.out.println(bJa);
// >> hello
// >> こんにちは
// >> world
// >> ワールド
IntelliJ IDEA を使用して動作確認していた際、プロパティファイルのエンコーディングが ISO-8859-1 になっていて文字化けしたため、プロパティファイルの保存時に UTF-8 へ変更する必要があった。
MissingResourceException
ロケールを指定してリソースバンドルを取得しようと試みた際に、仮に対象のロケールに基づくプロパティファイルが見つからなかった場合、デフォルトのプロパティファイル(MyResources.properties)が存在しないと java.util.MissingResourceException が発生する。
