ImmutableList 与 Arrays.asList 的 Null 指针取消引用差异解析
2024-03-09 09:13:16
Null 指针取消引用警告:ImmutableList 与 Arrays.asList 的差异
介绍
在使用 FindBugs 工具分析代码时,我们经常会遇到“null 指针取消引用”警告。这种警告表示某个方法返回的值可能为 null,进而可能导致空指针异常。然而,我们发现,对于相同的输入,针对 ImmutableList.of(..) 的“null 指针取消引用”警告适用于 ImmutableList.of(..) 而对 java.util.Arrays.asList(..) 却不适用。本文将探讨导致这种差异的原因并提出解决方法。
ImmutableList 与 Arrays.asList 的区别
要理解这种差异,我们需要了解 ImmutableList 和 Arrays.asList 在内部如何处理空值。
ImmutableList 是一个不可变集合,意味着创建后不能修改。如果向 ImmutableList 中添加一个空值,则会引发 NullPointerException。
Arrays.asList 返回一个受底层数组支持的 List 视图。如果底层数组中存在空值,则该视图不会引发 NullPointerException,但访问该空值仍会导致 NullPointerException。
FindBugs 警告差异的原因
在给定的示例中,当使用 ImmutableList.of(object.getName()) 时,FindBugs 正确识别出存在空指针取消引用的潜在风险,因为 object.getName() 可能返回 null,而 ImmutableList 不允许空值。
另一方面,当使用 Arrays.asList(object.getName()) 时,FindBugs 不会发出警告,因为该视图不会引发 NullPointerException,即使底层数组中存在空值。
解决方法
要解决此问题,我们应该始终注意我们使用的集合类型,并确保所使用的集合类型与我们的意图相匹配。在上面的示例中,我们可以使用以下方法之一:
- 使用 Optional.ofNullable(object.getName()) 来安全地将 object.getName() 的值包装到 Optional 中,然后调用 ImmutableList.of(optional.orElse(null))。
- 在使用 Arrays.asList(object.getName()) 之前,先使用 Objects.requireNonNull(object.getName()) 来检查 object.getName() 是否为 null。
结论
了解不同集合类型在处理空值方面的差异非常重要。通过仔细选择集合类型并注意潜在的空指针取消引用风险,我们可以编写更健壮、更可靠的代码。
常见问题解答
-
为什么 FindBugs 会发出针对 ImmutableList.of(..) 的警告而不会针对 Arrays.asList(..) 发出警告?
因为 ImmutableList 不允许空值,而 Arrays.asList 返回的视图即使存在空值也不会引发 NullPointerException。
-
如何解决针对 ImmutableList.of(..) 的警告?
使用 Optional.ofNullable 或 Objects.requireNonNull 来安全地处理空值。
-
为什么使用 Arrays.asList(..) 时不推荐使用 NullPointerException?
因为这样会导致难以追踪的空指针异常,因为实际的空值可能存在于底层数组中。
-
有什么其他方法可以安全地处理空值?
除了上述方法外,还可以使用 Guava 的 Preconditions 类或 Apache Commons Lang3 的 StringUtils 类来处理空值。
-
如何选择正确的集合类型?
考虑集合的预期使用情况、所需的性能和空值处理要求。对于不可变集合和严格的空值处理,请选择 ImmutableList。对于可变集合和较宽松的空值处理,请选择 Arrays.asList。