我正在尝试在我的类中使用默认的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);
//
答案 0 :(得分:123)
java.util.Properties
实现java.util.Map
接口,因此可以只是这样处理它,并使用putAll
之类的方法添加另一个Map
的内容{1}}。
但是,如果您将其视为地图,则需要非常小心:
new Properties(defaultProperties);
这通常会让人们感到困惑,因为看起来像一样复制构造函数,但事实并非如此。如果您使用该构造函数,然后调用类似keySet()
(继承自其Hashtable
超类)的内容,则会获得一个空集,因为Map
Properties
方法Properties
不要考虑传递给构造函数的默认Properties
对象。只有在使用getProperty
本身定义的方法时才会识别默认值,例如propertyNames
和Properties merged = new Properties();
merged.putAll(properties1);
merged.putAll(properties2);
等。
因此,如果您需要合并两个Properties对象,则执行此操作会更安全:
Properties
这将为您提供更可预测的结果,而不是任意将其中一个标记为“默认”属性集。
通常情况下,我建议不要将Map
视为Hashtable
,因为(在我看来)这是Java早期的实现错误(属性应该包含Properties
},而不是扩展它 - 这是懒惰的设计),但{{1}}中定义的贫血界面本身并没有给我们很多选择。
答案 1 :(得分:19)
假设您最终想要从文件中读取属性,我会在同一个属性对象中加载这两个文件,如:
Properties properties = new Properties();
properties.load(getClass().getResourceAsStream("default.properties"));
properties.load(getClass().getResourceAsStream("custom.properties"));
答案 2 :(得分:4)
你差不多好了:
Properties defaultProperties = new Properties();
defaultProperties.setProperty("key1", "value1");
defaultProperties.setProperty("key2", "value2");
Properties finalProperties = new Properties(defaultProperties);
finalProperties.setProperty("key2", "value3");
编辑:将put
替换为setProperty
。
答案 3 :(得分:1)
是的,你只是调用putAll方法,你已经完成了。
答案 4 :(得分:1)
的putAll(): 将指定映射中的所有映射复制到此哈希表。这些映射将替换此哈希表对当前在指定映射中的任何键所具有的任何映射。
Properties merged = new Properties();
merged.putAll(properties1);
merged.putAll(properties2);
第2行根本没有效果。第一个文件中的所有属性都不在合并的属性对象中。