Hi all,

I'd like to share a quick data point in support of JDK-8268665
<https://bugs.openjdk.org/browse/JDK-8268665>, which proposes deprecating
the legacy contains(Object) methods on ConcurrentHashMap and Hashtable.

At Google, Error Prone's HashtableContains
<https://errorprone.info/bugpattern/HashtableContains> check has banned
calling these methods in Java code for years, since callers almost always
mean containsKey(Object) rather than containsValue(Object).

However, we recently realized that we hadn't ported HashtableContains to
Android Lint, which analyzes both Java and Kotlin code. When we audited the
existing Kotlin usages of ConcurrentHashMap.contains(Object) in our
codebase, all of them were attempting to check key presence!

This is an especially easy trap to fall into in Kotlin: the Kotlin stdlib
defines operator fun Map.contains(key) as an extension function that
delegates to containsKey(key) (allowing both k in map and map.contains(k)).
However, if the receiver is typed as ConcurrentHashMap or Hashtable, the
legacy contains(Object) member method wins overload resolution over the Map
extension and silently checks containsValue instead. In Kotlin, this will
additionally start generating warnings on k in hashtable (see KT-48007
<https://youtrack.jetbrains.com/issue/KT-48007>, k in concurrentHashMap is
already special-cased <https://youtrack.jetbrains.com/issue/KT-18053> as an
error).

Would there be any appetite to revisit deprecating
ConcurrentHashMap.contains(Object) and Hashtable.contains(Object) in the
JDK (JDK-8268665 <https://bugs.openjdk.org/browse/JDK-8268665>) so that
javac, kotlinc, and IDEs warn on this out of the box?

Thanks,

-Kurt Alfred Kluever

Java and Kotlin Ecosystems, Google

Reply via email to