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