如何合并两个java.util.Properties对象?

Igo*_*gor 59 java properties

我试图java.util.Properties在我的类中有一个默认对象,它接受默认属性,让开发人员通过指定另一个java.util.Properties对象来覆盖其中一些,但我找不到一个很好的方法.

预期用途如下:

Properties defaultProperties = new Properties();
defaultProperties.put("key1", "value1");
defaultProperties.put("key2", "value2");

Properties otherProperties = new Properties();
otherProperties.put("key2", "value3");

Properties finalProperties = new Properties(defaultProperties);

//
// I'd expect to have something like:
// 
// finalProperties.merge(otherProperties);
//
Run Code Online (Sandbox Code Playgroud)

ska*_*man 125

java.util.Properties实现java.util.Map接口,所以你可以这样处理它,并使用类似的方法putAll来添加另一个的内容Map.

但是,如果您将其视为地图,则需要非常小心:

new Properties(defaultProperties);
Run Code Online (Sandbox Code Playgroud)

这通常会让人们失望,因为它看起来像一个复制构造函数,但事实并非如此.如果你使用那个构造函数,然后调用类似的东西keySet()(从它的Hashtable超类继承),你将得到一个空集,因为这些Map方法Properties没有考虑Properties你传递给构造函数的默认对象.只有在使用Properties自身定义的方法(例如getProperty和等)时propertyNames,才会识别默认值.

因此,如果您需要合并两个Properties对象,则执行此操作会更安全:

Properties merged = new Properties();
merged.putAll(properties1);
merged.putAll(properties2);
Run Code Online (Sandbox Code Playgroud)

这将为您提供更可预测的结果,而不是任意将其中一个标记为"默认"属性集.

通常情况下,我建议不要将其Properties视为a Map,因为那是(在我看来)Java早期的一个实现错误(属性应该包含一个Hashtable,而不是扩展它 - 这是懒惰的设计),但是贫困界面在Properties本身并没有给我们很多选择.

  • 将Properties视为Map的另一个危险是它不是"Genericified":`properties.put("key",new Object())`将编译. (2认同)

EJB*_*EJB 19

假设您最终想从文件中读取属性,我会在同一个属性对象中加载两个文件,如:

Properties properties = new Properties();
properties.load(getClass().getResourceAsStream("default.properties"));
properties.load(getClass().getResourceAsStream("custom.properties"));
Run Code Online (Sandbox Code Playgroud)