WebシステムでPropertyファイルを起動時に読み込んでメモリ上に展開することはよくあることだと思います。
で、それをEnumでやったらこうなる!というのを作ってみました。
PropertyHolder.java
package property;
import java.util.Properties;
import java.util.Set;
public enum PropertyHolder {
Hoge("hoge.properties"), Foo("foo.properties"), Bar("bar.properties");
private Properties properties;
private String fileName;
static {
System.out.println("staticイニシャライザ開始");
for (PropertyHolder p : values()) {
System.out.println("static:" + p.name());
p.init();
}
}
private PropertyHolder(String fileName) {
System.out.println("constructor:" + fileName);
this.fileName = fileName;
}
private void init() {
System.out.println("init:" + fileName);
properties = new Properties();
try {
properties.load(getClass().getClassLoader().getResourceAsStream(
fileName));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public String get(String key) {
return properties.getProperty(key);
}
public String getAll() {
System.out.println("getAll:" + fileName);
Set<Object> keys = properties.keySet();
StringBuilder sb = new StringBuilder();
for (Object obj : keys) {
String key = (String) obj;
sb.append("[");
sb.append(key);
sb.append(":");
sb.append(get((String) obj));
sb.append("]");
}
return sb.toString();
}
}
Main.java
package property;
public class Main {
public static void main(String[] args) {
System.out.println("Hoge.get(\"a\"):" + PropertyHolder.Hoge.get("a"));
System.out.println("Hoge.getAll():" + PropertyHolder.Hoge.getAll());
System.out.println("Foo.getAll():" + PropertyHolder.Foo.getAll());
System.out.println("Bar.getAll():" + PropertyHolder.Bar.getAll());
}
}
hoge.properties
a=A b=B c=C
foo.properties
aa=AA bb=BB cc=CC
bar.properties
aaa=AAA bbb=BBB ccc=CCC
実行結果
constructor:hoge.properties constructor:foo.properties constructor:bar.properties staticイニシャライザ開始 static:Hoge init:hoge.properties static:Foo init:foo.properties static:Bar init:bar.properties Hoge.get("a"):A getAll:hoge.properties Hoge.getAll():[b:B][a:A][c:C] getAll:foo.properties Foo.getAll():[aa:AA][bb:BB][cc:CC] getAll:bar.properties Bar.getAll():[bbb:BBB][aaa:AAA][ccc:CCC]
ポイントは、staticイニシャライザでEnumクラスの定数一つ一つがもっているinitメソッドを呼んでいるところですかね。
staticイニシャライザは1クラスに対して1回しか動かないので、Enumクラスの中に定数がいくつあっても、その定数ひとつに対して1回しかstaticイニシャライザが呼ばれないことは実行結果をみるとわかりますね。
staticイニシャライザを使うと例外がRuntimeExceptionしか出せないのがきついですね。 システム共通ランタイムExceptionクラスがある場合、そちらを使ってラップしてからスローするといいですね。
あとは、いちいちinitメソッドを作らずにコンストラクタでファイルを読んでもいいと思います。 場合によると思うので、使い分けてみてください。
※サンプルのgetAllメソッドは実際に使う時は不要だと思うので、削除して使ってください。