On 5/25/16 5:27 PM, Mandy Chung wrote:
On May 25, 2016, at 5:11 PM, Stuart Marks <stuart.ma...@oracle.com> wrote:
On 5/25/16 4:58 PM, Mandy Chung wrote:
Have you considered fixing this method to return a unmodifiable set and make 
this spec in JDK 9?  It’s a small change.

I did think about changing the behavior here but I decided against it because 
of the small compatibility risk.

I would suggest to make this small incompatible spec change in JDK 9 since it’s 
a major release.  This method was intended to filter out non-String keys in 
this Properties for iteration and it’s an oversight not to return an 
unmodifiable set.

OK. I did a survey at grepcode.com and there are a lot of uses of stringPropertynames(). The vast majority are either iterating over the returned set or copying the values into a new or existing set. These wouldn't be affected by making the returned set unmodifiable.

There are a handful of uses that simply return the set to the caller. From those it's really hard to tell how the set is used.

However, the existing implementation permits removal only; it already prohibits addition. Making the returned set unmodifiable would break clients that only remove elements from the returned set. I can imagine use cases that would do this, but it seems like they'd be quite rare.

In any case, the revised diff is appended below. I considered modifying enumerateStringProperties() to use a Set instead of a Map, but it doesn't really help, since a HashSet contains a HashMap anyway.

s'marks


diff -r 4d9388b1ae27 src/java.base/share/classes/java/util/Properties.java
--- a/src/java.base/share/classes/java/util/Properties.java Wed May 25 13:38:35 2016 -0700 +++ b/src/java.base/share/classes/java/util/Properties.java Thu May 26 13:55:35 2016 -0700
@@ -1037,18 +1037,18 @@
     }

     /**
-     * Returns a set of keys in this property list where
-     * the key and its corresponding value are strings,
+     * Returns an unmodifiable set of keys from this property list
+     * where the key and its corresponding value are strings,
      * including distinct keys in the default property list if a key
      * of the same name has not already been found from the main
      * properties list.  Properties whose key or value is not
      * of type {@code String} are omitted.
      * <p>
-     * The returned set is not backed by the {@code Properties} object.
-     * Changes to this {@code Properties} are not reflected in the set,
-     * or vice versa.
+     * The returned set is not backed by this {@code Properties} object.
+     * Changes to this {@code Properties} object are not reflected in the
+     * returned set.
      *
-     * @return  a set of keys in this property list where
+     * @return  an unmodifiable set of keys in this property list where
      *          the key and its corresponding value are strings,
      *          including the keys in the default property list.
      * @see     java.util.Properties#defaults
@@ -1057,7 +1057,7 @@
     public Set<String> stringPropertyNames() {
         Map<String, String> h = new HashMap<>();
         enumerateStringProperties(h);
-        return h.keySet();
+        return Set.of(h.keySet().toArray(new String[0]));
     }

     /**

Reply via email to