我想防止 getter 返回空值,就像下面的例子一样。这是一种不好的做法吗?
示例 1
public Integer getMinutes() {
if (minutes == null)
minutes = 0;
return minutes;
}
示例 2
public List getTasks() {
if (tasks == null)
tasks = new ArrayList();
return tasks;
}
最佳答案
简短的回答是:视情况而定。
更具体地说,如果不查看整个类并理解其设计,就不可能以一般方式回答这个问题。空值检查是一个实现细节,适用于某些设计,但在其他设计中可能会产生异味。
一般来说,方法必须符合它们的约定,仅此而已。所以从API设计的角度来看,这个问题是无关紧要的。您根据一长串现有最佳实践设计您的 API,然后设计您的实现以适应。这些设计最佳实践之一是您不应该将“零元素”特例化为 null
返回 Collection
时.也就是说,如果您的方法可以合理地返回一个空集合,它应该返回一个空集合,而不是像 null
这样的特殊值。 .这几乎总能简化客户端代码并消除一整类潜在的 NPE。这并不意味着您不能使用 null
在内部标记“零元素”,但这意味着如果您这样做,您应该在返回时执行转换(如您的示例中所示)。
因此,如果您的 getTasks()
方法指定它始终返回一个(可能为空)列表,在您的示例中使用空检查是一个合理的实现选择。在您的特定示例中,它可能不是最佳选择,因为 JDK 提供了类似 Collections.emptyList<T>()
的方法。 ,它允许您廉价地重复使用单例空列表实例,因此您不会在内存中保存任何内容,并且 CPU 节省值得怀疑1。
此外,通过使用“null
表示空列表”约定,您要求所有内部方法都必须检查 tasks == null
,或者使用 getTasks() 方法。在集合对象的特定情况中,我通常更喜欢使用 Collections.empty*
方法而不是 null 来表示空列表2。类似的推理适用于 Integer
自Integer.valueOf(0)
以来的案例在 all compliant JVMs 上返回一个单例对象.
撇开那些特定的情况不谈,肯定有理由使用 null 检查来表示缺失或默认元素,特别是当没有好的“空”元素出现或性能很重要时。您会发现这种模式在设计良好的库(例如 Java 运行时和 Guava)中使用得比较频繁。所以你不能说这是一个不好的做法。这是一种需要仔细评估的做法。
1这些的使用Collection.empty*
方法也适用于您的示例。在您的 null 情况下,您可以考虑直接返回 Collections.emptyList()
,而不是创建一个新的 ArrayList
一经请求。这是否合适取决于整体类设计,例如,该列表是否可变。
2是否Collections.emptyList()
比显式空检查更快实际上是一个复杂的问题。如果空列表非常罕见,通常不会出现在给定进程中,则 emptyList()
方法可能更快,因为随着空列表的频率变为零,它的成本( setter/getter )变为零。另一方面,当确实出现空列表时,它可能会为所有使用 List
的方法创建一个多态调用站点。 : 每个这样的网站都可能看到一个特殊的“空列表”实现和 ArrayList
.这会减慢代码速度,尽管很大程度上取决于内联决策。因此,与通常的性能考虑一样,确切的答案很复杂,如果细节很重要,您需要分析。
关于java - 在从 getter 返回之前检查 null 是一种不好的做法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37891203/