JDK-8221924 : get(null) on single-entry unmodifiable Map returns null instead of throwing NPE
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util:collections
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2019-04-03
  • Updated: 2019-07-31
  • Resolved: 2019-04-09
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 11 JDK 12 JDK 13
11.0.4Fixed 12.0.2Fixed 13 b16Fixed
Related Reports
CSR :  
Description
The unmodifiable maps are supposed to be null-hostile. However, a one-entry unmodifiable map will simply return null when get(null) is called. This is inconsistent with the behavior of other unmodifiable maps that have different numbers of elements.

Map.of().get(null) ==> throws NPE
Map.of(1, 2).get(null) ==> returns null
Map.of(1, 2, 3, 4).get(null) ==> throws NPE

Moreover, containsKey(null) and containsValue(null) on all unmodifiable maps throw NPE, and contains(null) on unmodifiable lists and sets all throw NPE. Thus, the get(null) behavior should be modified also to throw NPE.

Thanks to Claes Redestad for spotting this.

This fix should be backported to 12 and 11 as well.
Comments
Fix Request (for jdk11u and jdk12u) This is a small behavioral change that improves the consistency of the unmodifiable collections and that will potentially reduce programming errors. It's a behavioral change that adds a restriction (throws NPE instead of silently accepting a null argument) but I think the incompatibility risk is worth it. Since we are early in the JDK 11 LTS cycle, and these APIs didn't appear in JDK 8 -- they were introduced in JDK 9 -- most projects upgrading from JDK 8 to JDK 11 probably haven't been exposed to this behavior yet. Since JDK 11 will have a long lifetime, it's worth getting this in now. See the CSR (JDK-8222002) for more details. Patch applies to both jdk11u and jdk12u cleanly. Relevant tier1, tier2, and tier3 tests all pass.
10-04-2019

Review thread: http://mail.openjdk.java.net/pipermail/core-libs-dev/2019-April/059533.html
05-04-2019