概要
Properties ファイルは、DB 接続先、タイムアウト値、機能フラグなど、アプリケーションの設定を外出しする標準的な手段です。Java 標準の Properties クラスで読み書きできますが、文字コードの扱いに落とし穴があります。Properties.load(InputStream) は ISO-8859-1 でしか読めないため、日本語を含む設定ファイルでは InputStreamReader で UTF-8 を明示する必要があります。この記事では、クラスパスからの読み込み、ファイルパスからの読み込み、デフォルト値付きの安全な取得、数値変換を整理し、実務でそのまま使えるユーティリティメソッドを提供します。
使いどころ
アプリケーションの DB 接続先やタイムアウト値を application.properties に外出しして環境ごとに切り替える
バッチ処理の実行パラメータ(対象日、リトライ回数など)を設定ファイルで管理する
テスト環境と本番環境で異なるフラグ値をプロパティファイルで制御する
コード例
import java.io.FileNotFoundException;
public class PropertiesConfig {
/** クラスパスからプロパティファイルを読み込む */
public static Properties loadFromClasspath(String resourceName) throws IOException {
InputStream is = PropertiesConfig.class.getClassLoader()
.getResourceAsStream(resourceName);
if (is == null) {
throw new FileNotFoundException("リソースが見つかりません: " + resourceName);
}
var props = new Properties();
try (var reader = new java.io.InputStreamReader(is, StandardCharsets.UTF_8)) {
props.load(reader);
}
return props;
}
/** ファイルパスからプロパティファイルを読み込む */
public static Properties loadFromFile(Path path) throws IOException {
var props = new Properties();
try (var reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
props.load(reader);
}
return props;
}
/** デフォルト値付きで安全に取得 */
public static String get(Properties props, String key, String defaultValue) {
return props.getProperty(key, defaultValue);
}
/** 数値として取得(変換失敗時はデフォルト値) */
public static int getInt(Properties props, String key, int defaultValue) {
var value = props.getProperty(key);
if (value == null) return defaultValue;
try {
return Integer.parseInt(value.trim());
} catch (NumberFormatException e) {
return defaultValue;
}
}
public static void main(String[] args) {
var props = new Properties();
props.setProperty("db.url", "jdbc:postgresql://localhost:5432/mydb");
props.setProperty("app.name", "業務アプリ");
props.setProperty("timeout.seconds", "30");
System.out.println(get(props, "db.url", ""));
System.out.println(get(props, "max.retry", "3"));
System.out.println(getInt(props, "timeout.seconds", 60));
}
}Version Coverage
var で記述が簡潔になる。Files.newBufferedReader() のデフォルトが UTF-8 のため文字コード指定を省略できる(Java 11+)。
// Java 17: var + Files.newBufferedReader()
var props = new Properties();
try (var reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
props.load(reader);
}
var value = props.getProperty("db.url", "jdbc:h2:mem:");Library Comparison
注意点
Properties.load(InputStream) は ISO-8859-1 で読み込むため、日本語値が文字化けする。必ず InputStreamReader + UTF-8 でラップすること。
getProperty() は存在しないキーで null を返す。NullPointerException を避けるため、デフォルト値付きの getProperty(key, default) を使うこと。
数値プロパティを Integer.parseInt() で変換する際、値が空文字や不正文字列の場合に NumberFormatException が発生する。try-catch でデフォルト値に戻す処理を入れること。
FAQ
InputStreamReader で UTF-8 を明示すれば問題ありません。native2ascii は Java 9 以降では不要です。
Properties は内部的に Hashtable を継承しているため順序は保証されません。順序が必要なら LinkedHashMap に詰め替えてください。
System.getenv() で環境変数を取得し、存在しなければプロパティファイルの値にフォールバックするパターンが一般的です。