Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
413 views
in Technique[技术] by (71.8m points)

generics - Why does java.util.Properties implement Map<Object,Object> and not Map<String,String>

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...