为什么Java List允许空值?

6
如果我正在撰写代码
List<String> list1 = new ArrayList<String>();
list1.add(null);
list1.add(null);

Java允许这样做。为什么?

任何使用list1 [0]的方式都将导致NPE。


2
尝试使用list1.get(0),它不会返回NPE。 - ashishmaurya
list1[0]甚至无法编译,因此这个问题本身就没有多大意义。 此外,正如其他人所指出的那样,对于列表的正确语法(list1.get(0)),在空值上不会抛出NPE,而只会返回null。 在发布问题之前,请至少进行最基本的研究... - Oskar Hýbl
1
你能想象如果每次插入空值时list.add()都抛出异常会怎样吗?哦,等等,List.of(...)就是这样的。摇头。 - Josh M.
1
@JoshM。是的,我刚刚被这个问题咬了一口,我原以为只是一个不重要的非破坏性重构,使用了List.of()。哦,Java,你的不一致性让人失望。 - Matt Craig
5个回答

19

Java允许这样做。为什么?

因为List是对象引用的集合。由于对于所有类型来说null都是一个有效的引用,所以编译器允许这样的语句: list1.add(null)


6

首先,你不能像array那样访问list元素,例如list1[0],如果你想从list中访问,你需要写成list.get(0)

针对你真正的问题,它不会导致NPE,并且列表允许你向其中添加null。当你尝试返回时,它仅返回null

如果你试图在结果为null的对象上调用方法/变量,则会遇到NPE。


6
任何使用list1[0]的方式都会导致NPE错误。不,不会:
List<String> list1 = new ArrayList<String>();
list1.add(null);
String foo = list1.get(0);    // No NPE here
if (foo == someOtherObject) { // Nor here
    // Do something
}

List 维护了一系列对象引用。对象引用可以是指向有效、存在的对象的引用,也可以是 null,表示它们目前不包含对象引用。

在语义上,包含一个 null 条目的 List 与完全没有该位置条目的 List不同的。完全没有一个条目可能很容易与在特定位置有一个带有 null 的条目或一个非 null 条目具有不同的含义。


1
这取决于List的实现方式。接口本身并不强制是否允许使用null值。
从文档documentation中可以看到:
与集合不同,列表通常允许重复元素。更正式地说,列表通常允许成对的元素e1和e2,使得e1.equals(e2),如果它们允许空元素,则通常允许多个空元素。
再次引用:
一些列表实现对其可能包含的元素有限制。例如,一些实现禁止使用null元素,并且有些对其元素类型有限制。尝试添加不合格的元素会抛出未经检查的异常,通常是NullPointerException或ClassCastException。

1

ArrayList允许使用null元素,

实现了所有可选的列表操作,并允许包括null在内的所有元素。

但是并不保证其他实现也一定允许。

例如,Java9 List.of()不允许使用null元素。:

它们不允许使用null元素。试图使用null元素创建它们会导致NullPointerException异常。

另请参阅Collection javadoc

某些集合实现对其可能包含的元素有限制。例如,某些实现禁止null元素,而某些实现则对其元素的类型有限制。尝试添加不合格的元素会抛出未经检查的异常,通常为NullPointerException或ClassCastException。


他们不允许空元素。试图使用空元素创建它们会导致NullPointerException。很抱歉,但这太愚蠢了。 - Josh M.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接