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
が発生する。