Nope, it's still a Hashtable<?,?>, i.e. a Hashtable<Object,Object>. Where is all this going? Well I had a class that had a Properties object as a member variable. I had a method that needed to return all the property names of that Properties object. I thought it would make sense for my method to return a Collection<String>. Since Properties extends Hashtable, I could just return it's keySet() method. This is a Set of all the keys in the Hashtable backing the Properties, thus it is a Set of Strings (Set<String>) and thus a Collection<String>. Too easy.
Wrong again. The return type of the keySet() method is a Set<object>, because Properties extends Hashtable<Object,Object>. You cannot case a Set<Object> to a Set<String>. I was very surprised by this. I expected to have throw a @SuppressWarning("unchecked") annotation on my method, but I did not expect that it would be a compilation error. I figure this is because I would be casting a generic interface. I guess. I could do something completely ridiculous:
return (HashSet<String>)new HashSet(myProps.keySet());
This worked with a good 'ol @SuppressWarning("unchecked") annotation. I had to copy my keySet() into a concrete Set object, and then I could cast. Totally ridiculous.
This all came because my Properties object was being injected with Spring. In other words I had a Spring context file with something like:
I simply replaced this with a map:
<entry key="a" value="1">
I could then make myProps into a Map<String,String> instead of a Properties object, and simply return it's keySet() without any casting. Very nice. So this just brings me back to the original question of why doesn't Properties extend Hashtable<String,String>?