内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用
我试图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);
//
java.util.Properties
实现java.util.Map
接口,所以你可以直接对待它,并使用方法putAll
来添加另一个的内容Map
。
但是,如果你把它当作Map来对待,你需要非常小心:
new Properties(defaultProperties);
这经常会把人们赶出去,因为它看起来像一个拷贝构造函数,但事实并非如此。如果使用该构造函数,然后调用类似keySet()
(从其Hashtable
超类继承的),则会得到一个空集,因为这些Map
方法Properties
不考虑Properties
传递给构造函数的默认对象。如果您使用Properties
自身定义的方法(例如getProperty
和propertyNames
其他方法),则只会识别默认值。
所以如果你需要合并两个Properties对象,这样做更安全:
Properties merged = new Properties();
merged.putAll(properties1);
merged.putAll(properties2);
这将为您提供更可预测的结果,而不是任意将其中一个标记为“默认”属性集。
通常情况下,我会建议不要把它Properties
看作是一个Map
,因为这是(在我看来)Java早期的一个实现错误(属性应该包含一个Hashtable
,没有扩展它 - 这是懒惰的设计),但是在Properties
本身并没有给我们很多选择。
假设你最终想从一个文件读取属性,我会去加载这两个文件在相同的属性对象,如:
Properties properties = new Properties();
properties.load(getClass().getResourceAsStream("default.properties"));
properties.load(getClass().getResourceAsStream("custom.properties"));