Propertiesクラスのデフォルトプロパティは使わない方がいいかも

Javaでは、プロパティの設定によく Properties クラスを使います。
このクラスは、コンストラクタで別のプロパティをデフォルト値として指定することができます。

public Properties(Properties defaults)
指定されたデフォルト値を持つ空のプロパティリストを作成します。

Properties (Java Platform SE 6)


最初に見たとき、これは便利そうと思いましたが・・・、
でも、このデフォルト値を指定するコンストラクタは、あまり使わない方がいいかもしれません。


場合によって、デフォルト値が読みとられないためです。

なぜ?

Properties クラスは Hashtable クラスを継承しているので、プロパティを取得するためのメソッドが、Properties#getProperty(String)Hashtable#get(Object)の二つ存在してしまっています。
このうち、前者は Hashtable を見て値が設定されていなければデフォルト値を返しますが、後者は Hashtable しか見ません。


そのため、プロパティを使う側が Hashtable#get(Object) を使っていたら、デフォルト値が使われません。
たとえば、JavaMail がこれに該当します・・・。

対策

最初にも書きましたが、デフォルト値を持つプロパティは使用しない方がよさそうです。
ただ、どうしてもそういう風な使い方をしなくてはならないときは、空のコンストラクタを使った上で、デフォルトにしたいプロパティを putAll でコピーするのがいいかもしません。
(ただし、Properties クラスは putAll の使用を推奨していません

public static Properties newProperties(Properties defaults){
	Properties p = new Properties();
	p.putAll(defaults);
	
	return p;
}

そもそも

Effective Java でも指摘されていますが、典型的な委譲と継承を間違えたことによる弊害です・・・。
自分も、以前逆に作って、あとから機能追加しずらくなってしまったことがあります。
本当に、設計ミスはあとあとやっかいですね・・・。