How to merge two java.util.Properties objects?

java, properties

Solution

`java.util.Properties` implements the `java.util.Map` interface, and so you can just treat it as such, and use methods like `putAll` to add the contents of another `Map`.

However, if you treat it like a Map, you need to be very careful with this:

new Properties(defaultProperties);

This often catches people out, because it looks like a copy constructor, but it isn't. If you use that constructor, and then call something like `keySet()` (inherited from its `Hashtable` superclass), you'll get an empty set, because the `Map` methods of `Properties` do not take account of the default `Properties` object that you passed into the constructor. The defaults are only recognised if you use the methods defined in `Properties` itself, such as `getProperty` and `propertyNames`, among others.

So if you need to merge two Properties objects, it is safer to do this:

Properties merged = new Properties();
merged.putAll(properties1);
merged.putAll(properties2);

This will give you more predictable results, rather than arbitrarily labelling one of them as the "default" property set.

Normally, I would recommend not treating `Properties` as a `Map`, because that was (in my opinion) an implementation mistake from the early days of Java (Properties should have contained a `Hashtable`, not extended it - that was lazy design), but the anemic interface defined in `Properties` itself doesn't give us many options.

Problem

I'm trying to have a default `java.util.Properties` object in my class, with the default properties it accepts, and let the developer override some of them by specifying another `java.util.Properties` object, but I couldn't find a nice way for doing that. The intended usage is the following: ``` 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); // ```

Original source