The java.util.Properties
class is meant to represent a map where the keys and values are both Strings. This is because Properties
objects are used to read .properties
files, which are text files.
So, why in Java 5 did they retrofit this class to implement Map<Object,Object>
and not Map<String,String>
?
The javadoc states:
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.
Since the keys and values are both supposed to be Strings then why not enforce that statically by using the proper generic type?
I guess making Properties
implement Map<String,String>
would not be fully backward compatible with code written for pre-Java 5. If you have older code that sticks non-strings into a Properties object then that code would no longer compile with Java 5. But... isn't that a good thing? Isn't the whole point of generics to catch such type errors at compile time?
Properties class allows String key/value pairs to read from or write to a stream. You may have have several application specific parameters to be read at the application startup you can utilize Properties class. HashMap is a collection class which allows to use key/value pairs of objects.
Because they did it in a hurry in the early days of Java, and didn't realise what the implications would be four versions later.
Generics were supposed to be part of the design of Java from the beginning, but the feature was dropped as being too complicated and, at the time, unnecessary. As a result, lots of code in the standard libraries is written with the assumption of non-generic collections. It took the prototype language "Pizza" from Martin Odersky to show how they could be done fairly well while maintaining near perfect backwards compatibility, with both Java code and bytecode. The prototype led to Java 5, in which the collections classes were retrofitted with generics in a way that allowed old code to keep working.
Unfortunately, if they were to retroactively make Properties
inherit from Map<String, String>
, then the following previously valid code would stop working:
Map<Object, Object> x = new Properties() x.put("flag", true)
Why anybody would do that is beyond me, but Sun's commitment to backwards compatibility in Java has gone beyond heroic into the pointless.
What's now appreciated by most educated observers is that Properties
should never have inherited from Map
at all. It should instead wrap around Map
, exposing only those features of Map that make sense.
Since reinventing Java, Martin Odersky has gone on to create the new Scala language, which is cleaner, inherits fewer mistakes, and breaks new ground in a number of areas. If you're finding Java's niggles annoying, take a look at it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With