Properties クラスを一言でいうと
java.util.Properties は、
「文字列のキーと文字列の値を、設定ファイル的に管理するためのクラス」
です。
ざっくり言うと、Map<String, String> みたいなものですが、
key=value形式の設定ファイル(.properties)を簡単に読み書きできる- デフォルト値の仕組みがある
- Java 標準のいろいろなライブラリでもよく使われる
という、設定情報専用の「古くて今も現役」のクラスです。
基本イメージ:文字列キーと文字列値の小さな辞書
Map と似ているけれど「設定情報に特化」
Properties は、内部的にはほぼ Hashtable<Object, Object> のサブクラスですが、実際には「キーも値も文字列で使うもの」と考えてください。
例えば、次のような情報を持てます。
"host" = "localhost""port" = "8080""mode" = "dev"
コード上では、次のように扱います。
import java.util.Properties;
public class PropertiesBasic {
public static void main(String[] args) {
Properties props = new Properties();
props.setProperty("host", "localhost");
props.setProperty("port", "8080");
props.setProperty("mode", "dev");
String host = props.getProperty("host");
String port = props.getProperty("port");
String mode = props.getProperty("mode");
System.out.println(host);
System.out.println(port);
System.out.println(mode);
}
}
JavasetProperty(String key, String value)getProperty(String key)
この 2 つが基本中の基本です。
値はすべて文字列として扱う
Properties は、「何でも文字列」として扱います。
数値っぽいものも、真偽値っぽいものも、一度は文字列です。
props.setProperty("maxUsers", "100");
props.setProperty("debug", "true");
Java取り出すときに、必要なら Integer.parseInt(...) や Boolean.parseBoolean(...) で変換します。
ここを割り切ってしまうと、Properties はとても扱いやすくなります。
.properties ファイルを読み込む(load)の基本
典型的な .properties ファイルの中身
例えば、config.properties というファイルに、こんな内容があるとします。
host=localhost
port=8080
mode=dev
# コメント行(# または ! で始まる)
debug=true
これを Properties で読み込むと、
先ほどの setProperty で入れたのと同じような状態になります。
ファイルから読み込む例(InputStream を使う)
最も基本的な読み込み方は、InputStream と load メソッドを使う方法です。
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class PropertiesLoadExample {
public static void main(String[] args) {
Properties props = new Properties();
try (FileInputStream in = new FileInputStream("config.properties")) {
props.load(in); // ファイル内容を読み込む
} catch (IOException e) {
e.printStackTrace();
}
String host = props.getProperty("host");
String port = props.getProperty("port");
String mode = props.getProperty("mode");
String debug = props.getProperty("debug");
System.out.println("host = " + host);
System.out.println("port = " + port);
System.out.println("mode = " + mode);
System.out.println("debug = " + debug);
}
}
Java流れを言葉で整理すると、
- 空の
Propertiesを作る FileInputStreamでファイルを開くprops.load(in)で、key=valueを全部読み込むgetPropertyで必要な値を取り出す
という感じです。
クラスパスから読み込む(リソースとして埋め込む)
アプリと一緒に .jar の中に入れてしまう形で、properties を読みたいことも多いです。
その場合は、クラスパス上のリソースとして読み込みます。
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class ClasspathPropertiesExample {
public static void main(String[] args) {
Properties props = new Properties();
try (InputStream in = ClasspathPropertiesExample.class
.getResourceAsStream("/config.properties")) {
if (in == null) {
System.out.println("config.properties がクラスパス上にありません");
return;
}
props.load(in);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("host = " + props.getProperty("host"));
}
}
Java/config.properties が、クラスパスのルートにある前提です。
アプリ設定やメッセージなどを「配布可能な形で同梱」したいときに、このスタイルはよく使われます。
.properties ファイルに書き出す(store)の基本
現在の設定をファイルに保存する
Properties には、現在持っているキー・値のペアを .properties 形式で書き出す store メソッドがあります。
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
public class PropertiesStoreExample {
public static void main(String[] args) {
Properties props = new Properties();
props.setProperty("host", "localhost");
props.setProperty("port", "8080");
props.setProperty("mode", "dev");
try (FileOutputStream out = new FileOutputStream("config.properties")) {
props.store(out, "Application configuration");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Javaこのコードを実行すると、config.properties に例えばこんな内容が書き出されます。
#Application configuration
#2025/12/27 12:34:56
host=localhost
mode=dev
port=8080
先頭にコメント(第二引数)とタイムスタンプ行が付き、そのあとに key=value の行が続きます。
注意点:文字コード(ISO-8859-1 と Unicode エスケープ)
Properties#load(InputStream) と store(OutputStream, ...) は、デフォルトでは ISO-8859-1(Latin-1)という文字コードを前提にしています。
そのため、日本語を含む文字は \uXXXX 形式の Unicode エスケープに変換されます。
例として、
props.setProperty("greeting", "こんにちは");
Javaを保存すると、ファイル内では次のように見えるかもしれません。
greeting=\u3053\u3093\u306b\u3061\u306f
古くからある仕様なので、挙動としては正しいのですが、
「ファイルを直接目で見て編集したい」ときには扱いづらいです。
最近は、
- UTF-8 の
Reader/Writerと組み合わせてload(Reader)/store(Writer, ...)を使う - そもそも
propertiesではなくYAMLやJSONを使う
という解決策を取ることが多いです。
とりあえず、「load(InputStream) / store(OutputStream, ...) は ISO-8859-1 前提」ということだけ覚えておいてください。
getProperty とデフォルト値の使い方
値がない場合にデフォルトを返すオーバーロード
getProperty には、第二引数にデフォルト値を渡せるオーバーロードがあります。
String host = props.getProperty("host", "localhost");
String port = props.getProperty("port", "8080");
Javaprops に "host" が入っていなければ "localhost" を返す、という動きです。
「設定ファイルに書いてあればそれを使う、書いてなければこの値を使う」というパターンに非常に便利です。
コンストラクタで「デフォルト Properties」を渡すやり方
Properties には、「デフォルト用の Properties を親として持つ」コンストラクタもあります。
import java.util.Properties;
public class DefaultPropertiesExample {
public static void main(String[] args) {
Properties defaults = new Properties();
defaults.setProperty("host", "localhost");
defaults.setProperty("port", "8080");
Properties props = new Properties(defaults);
// props に host を設定していないが、defaults から見つかる
System.out.println(props.getProperty("host")); // localhost
// 上書きもできる
props.setProperty("host", "example.com");
System.out.println(props.getProperty("host")); // example.com
}
}
Javanew Properties(defaults) としておくと、
props にキーがなければ defaults を見に行く
という挙動になります。
「アプリ全体のデフォルト設定」と「環境ごとの上書き設定」を分けたいときに便利です。
型付きの値を扱うときのパターン
int や boolean に変換する
Properties が返すのはすべて文字列なので、
実際に数値や真偽値として使いたい場合は、自分で変換します。
String maxUserStr = props.getProperty("maxUsers", "100");
int maxUsers = Integer.parseInt(maxUserStr);
String debugStr = props.getProperty("debug", "false");
boolean debug = Boolean.parseBoolean(debugStr);
JavaparseInt や parseBoolean は例外を投げたり、false になったりするので、
本番コードでは try-catch やバリデーションを合わせて考えるとより安全です。
まとめて設定オブジェクトに詰める
規模が大きくなってくると、「生の Properties をあちこちで直接触る」のはつらくなります。
よくあるパターンは、
Properties から値を読み出して、自分の Config クラスに詰める
それ以降は Config クラスのフィールドを使う
という形です。
public class AppConfig {
final String host;
final int port;
final boolean debug;
public AppConfig(Properties props) {
this.host = props.getProperty("host", "localhost");
this.port = Integer.parseInt(props.getProperty("port", "8080"));
this.debug = Boolean.parseBoolean(props.getProperty("debug", "false"));
}
}
Javaこうしておけば、アプリの他の部分では
config.hostconfig.portconfig.debug
のように型付きのフィールドにアクセスでき、
毎回 getProperty や parseInt を書かずに済みます。
Properties を使うときに意識したいこと
「小さめの設定」に向いた道具だと割り切る
Properties はシンプルで扱いやすい反面、
ネスト構造がない
配列やオブジェクト表現に弱い
全部文字列
という制約があります。
そのため、「アプリの設定の一部」「テスト用の簡易設定」「古くからあるライブラリとのやり取り」に使うくらいがちょうどよいです。
複雑な構造化設定を扱うなら、YAML / JSON / XML など、別のフォーマットとライブラリを使った方が自然です。
文字コードの罠を避ける
日本語を普通に書きたいなら、
load(Reader) / store(Writer, ...) を使い、InputStreamReader / OutputStreamWriter に UTF-8 を指定する
か、
必ず \uXXXX 形式で書く(現実的ではない)
のどちらかを選ぶ必要があります。
初心者のうちは、まずは「英数字の設定(host, port, mode など)」から始め、
文字コードの問題は少し慣れてから一段深く踏み込むのもいいと思います。
まとめ:Properties クラスを自分の中でこう位置づける
Properties を初心者向けにまとめると、
「文字列キー・文字列値の小さな辞書であり、key=value 形式の .properties ファイルを簡単に読み書きできる“設定用の入れ物”」
です。
意識しておくと良いポイントは、
キーも値も基本は文字列として扱うsetProperty / getProperty が基本操作load / store で .properties ファイルと簡単に行き来できる
デフォルト値を第二引数で渡したり、デフォルト用 Properties を親として持たせたりできる
複雑な設定には向かないので、「小さくシンプルな設定」に使う
