(已链接)BlockingQueue.put(null)抛出NullPointerException

11 java collections null nullpointerexception

我已经检查了实现,它是故意这样做的

 public void put(E e) throws InterruptedException {
     if (e == null) throw new NullPointerException();
Run Code Online (Sandbox Code Playgroud)

这种惊喜对于用户来说并不方便(例如,他想以这种方式用信号通知流的结尾)并打破与集合的一般契约,这很容易接受null元素.BlockingQueue区分null元素有什么意义?如果空值如此糟糕,我们可能会根本不使用它们并在JLS中强制执行此低值?

Lou*_*man 13

接受空值属于Collection合同的一部分.事实上,Collection Javadoc明确指出:

某些集合实现对它们可能包含的元素有限制.例如,某些实现禁止null元素,并且一些实现对其元素的类型有限制.尝试添加不合格的元素会引发未经检查的异常,通常是NullPointerException或ClassCastException.

在许多情况下,添加null到集合意味着程序中的某个程序存在错误,而不是故意将其置于某个程序中.例如,Guava库(我参与其中)明确决定从许多集合实现中拒绝空值,特别是不可变集合:

我们对Google的内部代码库进行了详尽的研究,结果表明,大约5%的时间内,集合中允许使用null元素,而其他95%的情况最好是通过在null上快速失败来实现的.

通常有变通办法接受空值,但许多集合的实现做出拒绝空值(其中大部分用户发现有用,因为它可以帮助他们找到的bug),以及对于在其中明确零点适合极少数情况下提供解决方法的决定.

老实说,我认为LinkedBlockingQueue这个类别的原因是在开发原始集合框架时所有这些都没有被弄清楚,但是在添加并发集合时这一点非常清楚.util.concurrent引用大部分工作的Doug Lea 被引述说,

Null糟透了.

在最坏的情况下,对象包装器或"毒物对象"始终是有效的解决方法; 番石榴提供了一个Optional类可以服务于在许多情况下的作用,这是广泛讨论这里在计算器上.

  • 问题是空值不能被完全禁止。除了完全破坏向后兼容性(Sun 和 Oracle 一直非常小心地不这样做,即使这意味着在 Java 中保留明显的错误和错误的库),您也无法避免它,例如在对象数组上:当您说“new String”时[5]`,如果不是`null`,数组还会填充什么?这很令人不快,但即使我们愿意,也不清楚我们能否摆脱它。 (2认同)
  • 四年后@Val FWIW - “BlockingQueue 有什么特别之处需要它来阻止空值?”。嗯,一方面,“poll(long timeout, TimeUnit unit)”使用“null”来表示发生了超时。如果该类使用“TimeoutException”来实现此目的,那么允许“null”值可能就可以了,但事实并非如此。 (2认同)