Saving a configuration in a Property Map
Java includes a property map, which can be used to store a configuration. It's a special kind of map where both the keys and values are strings and it allows values to easily be saved to or read from a file. The Properties
class is the concrete implementation of a property map.
For the sake of brevity, I'm not going to include any exception handling code. However, you can find a full working example that corresponds to this post as a GitHub Gist.
Defining a Properties instance
Let's take a look at how a Properties object can be defined and values can be stored inside it:
Properties props = new Properties();
props.setProperty("version", "1.4.2");
props.setProperty("author", "Joe Bloggs");
If you're familiar with a maps in Java, this is similar to using put()
. The Properties
class implements the Map<Object, Object>
interface, so do you have methods like get()
and put()
. The use of methods like these are not recommended since you could insert anything you want (recall that everything inherits from Object
– the cosmic superclass). With the Properties-defined methods such as getProperty()
and setProperty()
, you get type safety.
Saving to a file
Now that we have defined our Properties
instance, let's save the values to a file:
FileOutputStream out = new FileOutputStream("conf.properties");
props.store(out, "Configuration Properties");
The constructor argument in FileOutputStream
is the name of the file we want to save to. Note that this does file does not need to exist yet. The file format does not need to be .propertes
– I've included it only for readablity.
The second argument to store()
is a comment that will be stored at the top of the file.
This is what gets stored:
#Configuration properties
#Tue Jun 30 12:19:03 BST 2020
author=Joe Bloggs
version=1.4.2
Reading from a file
This is how you would load the contents of a properties file into a Properties
instance:
FileInputStream in = new FileInputStream("conf.properties");
props.load(in);
Retrieving values
There are two (recommended) ways to fetch a property from your properties file. Let's start with the simplest:
String author = props.getProperty("author");
The method getProperty()
will look in the property file for a key named author
. Failing that, it will then search the default properties file. If no such key can be found, null
is returned.
Depending on your use case, you may want a default value to be returned if the key doesn't exist. This is the second way of retrieving a value:
String author = props.getProperty("author", "Sirius Black");
This time around, instead of returning null
if the author
key cannot be found, Sirius Black
is returned.
Alternatively, you can set a default when setting the property:
Properties defaultProps = new Properties();
defaultProps.setProperty("version", "v1.0.0");
defaultProps.setProperty("author", "Clark Kent");
Properties props = new Properties(defaultProps);
Here, we're creating another Properties
map called defaultProps
that stores default values.
While it's entirely possible to create multiple layers of default properties (i.e. one default Properties
object is set to the properties of another object), it's not recommended to go beyond one level.
Removing a property
A property can be removed by using remove(Object key)
. Since any type of key could be passed in, you need to be careful to only supply a String
.
Resources
There's lots of great material on this subject. Below are three examples that I used to write this post:
- Properties Javadoc page
- Oracle properties tutorial (Java 8)
- Core Java, Cay S. Horstmann. Section 9.7.3
Photo by Tierra Mallorca on Unsplash