RFR(xs): 8059361: Properties.stringPropertyNames() returns a set inconsistent with the assertions from the spec

Stuart Marks stuart.marks at oracle.com
Thu May 26 20:57:23 UTC 2016



On 5/25/16 5:27 PM, Mandy Chung wrote:
>> On May 25, 2016, at 5:11 PM, Stuart Marks <stuart.marks at 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]));
      }

      /**



More information about the core-libs-dev mailing list