Reputation: 11107
I have checked the implementation, it does so intentionally
public void put(E e) throws InterruptedException {
if (e == null) throw new NullPointerException();
This surprise is not convenient for user (who wants to signal end of stream this way, for instance) and breaks the general contract with collections, which easily accept the null elements. What is the point of BlockingQueue to discriminate null elements? If nulls are so bad, might be we should refrain using them at all and enforce this low in JLS?
Upvotes: 14
Views: 6191
Reputation: 198093
Accepting nulls is not part of the Collection
contract. Indeed, the Collection
Javadoc specifically states:
Some collection implementations have restrictions on the elements that they may contain. For example, some implementations prohibit null elements, and some have restrictions on the types of their elements. Attempting to add an ineligible element throws an unchecked exception, typically NullPointerException or ClassCastException.
In many cases, adding null
to a collection means there's a bug in your program somewhere, not that you put it in deliberately. For example, the Guava library (which I contribute to) makes the explicit decision to reject nulls from many of their collection implementations, specifically the immutable ones:
We did an exhaustive study on Google's internal code base that indicated that null elements were allowed in collections about 5% of the time, and the other 95% of cases were best served by failing fast on nulls.
There are generally workarounds that do accept nulls, but many collection implementations make the decision to reject nulls (which most users find helpful, as it helps them find bugs) and offer workarounds for the rare case where explicit nulls are appropriate.
In all honesty, I think the reason that LinkedBlockingQueue
is in this category is that all this hadn't been figured out when the original collections framework was developed, but it was pretty clear by the time that the concurrent collections were being added. Doug Lea, who did much of the work on util.concurrent
, has been quoted as saying,
Null sucks.
In the worst case, object wrappers or "poison objects" are always valid workarounds; Guava provides an Optional
class which can serve that role in many cases, which is discussed extensively here on StackOverflow.
Upvotes: 14