Java Properties
Basic definition
The Properties class represents a persistent set of String
pairs in Map
representation ("Key" -> "Value").
It can write those pairs to a disk and read them back to String
or Stream
.
This class is used for storing configs for applications.
If you are familiar with Linux or macOS (less likely, but I hope you are, and on Windows - dunno) operating system you probably edited some configuration files.
Usage
Setting Properties
To set properties instance we use the setProperty(String key, String value)
It calls the Hashtable
method put
and enforces use of strings for property keys and values. The value returned is the result of the Hashtable
call to put.
The construction of this metod should look like this:
| class Properties extends Hashtable<Object,Object> {
// ...
public synchronized Object setProperty(String key, String value) {
return put(key, value);
}
// ...
}
|
A you see, it uses synchronised
keyword, which provides support for parallelism with getProperty
method (it is synchronised
too)
Let see how it works on the example:
Warning
Because Properties
inherits from Hashtable
, the put and putAll
methods can be applied to a
Properties object.
Their use is strongly discouraged as they allow the caller to insert entries whose keys or
values are not Strings.
The setProperty
method should be used instead.
If the store or save method is called on a "compromised" Properties object that contains
a non-String key or value, the call will fail.
This is an example of breaking Liskov Substitution Principle.
They should use composition instead inheritance, but idk, too late I guess.
Here is an example that points out this bad design decision:
Storing Properties
You can store the property key and value pairs to a file via store()
method.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 | package collections.properties;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
public class StoreProperties {
public static void main(String[] args) throws IOException {
Properties prop = new Properties();
prop.setProperty("newkey1", "newvalue1");
prop.setProperty("newkey2", "newvalue2");
prop .store(new FileOutputStream(
"./src/collections/properties/properties.conf"), null);
// Store as XML
prop = new Properties();
prop.setProperty("1st", "first");
prop.setProperty("2nd", "second");
prop.storeToXML(new FileOutputStream(
"./src/collections/properties/properties.xml"), null);
}
}
|
- Content of
properties.conf
is:
| #Thu Oct 28 23:10:51 CEST 2021
newkey1=newvalue1
newkey2=newvalue2
|
| <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<entry key="1st">first</entry>
<entry key="2nd">second</entry>
</properties>
|
Loading Properties
Default Properties
There are two ways to provide default value for properties:
- With using
Properties
constructor which accepts another Properties
object as a parameter: Properties(Properties defaults)
:
As you see, after setting default properties you can't just browse through them.
There is no method in Properties
class that will show you default values
for keys. I am not a master of the good design, but this thing looks awful,
because a client might want ask: "Hmm, I wonder what are defaults of this app?",
and the answer is well... there is no answer.
- By providing default value with using method parameter:
getProperty(String key, String defaultValue)
If value for key does not exist, method returns defaultValue
String.