1、典型回答
简单来说,ConcurrentHashMap 不允许插入 null 值是JDK 源码规定的,如下源码所示(此源码基于JDK 1.8):
从上述源码可以看出,在添加方法的第一句就加了判断:如果 key 值为 null 或者是 value 值为 null,就直接抛出异常 NullPointerException 空指针异常,所以 ConcurrentHashMap 的 key 和 value 都不允许插入 null
2、全面剖析
也就是说,之所以 ConcurrentHashMap 不允许插入 null 是因为JDK 源码的规定,因为 JDK 源码规定不允许插入null 所以就不能插入 null,否则会报空指针异常.
深层次原因
那么问题来了,为什么JDK 源码不允许 ConcurrentHashMap 插入 null?
更深层次的原因是,ConcurrentHashMap 的设计是在多线程下使用的,而如如果 ConcurrentHashMap 的 key 或value 允许为 null 的话,那么程序就会存在二义性问题
什么是二义性问题?
所谓的二义性问题是指含义不清或不明确
如果我们假设 ConcurrentHashMap 允许插入 null,那么此时它就会有二义性问题,这个 null 值就有两层含义
- 这个 key 不存在,所以返回 null
- key 存在,并且值本身就为 null,所以返回的就是 null
而在多线程下,你没有办法证明真伪,因为你在判断证明的时候,其他线程可能同时做了修改,所以不能被证明的二义性问题需要从源头上杜绝,所以多线程下的 ConcurrentHashMap 是不允许key 和 value 插入 null 值的
注:Hashtable 也是不允许插入 null,原因和 ConcurrentHashMap 是一样的 (因为有二义性问题)
为什么 HashMap 允许插入 null 值?
因为 HashMap 设计是在单线程下使用的,而单线程可以证明真伪,它在进行查询判断的时候,不用担心有其他线程对这个值同时做修改,所以它不存在二义性问题,所以 HashMap 允许 key 和 value 都为 null。