java - 在从 getter 返回之前检查 null 是一种不好的做法吗?

标签 java oop null

我想防止 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。类似的推理适用于 IntegerInteger.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/

相关文章:

java - Java中是否存在用于满足接口(interface)的空方法的习语?

objective-c - 控制程序执行顺序的技术

php - 由数据库行组成的对象

sql - 使用可以为空的列测试不平等

java - Java 中的 OpenCV EAST 文本检测器实现

java - 在我的应用程序中,为什么 readInt() 总是抛出 EOFException?

javascript - addClass(undefined) 与 addClass(null)

mysql - 在 MySQL 中选择 NULL 和 NOT NULL 值

java - 从输入流读取实体时出错 Dropwizard 示例

java.lang.RuntimeException : java. lang.RuntimeException : Duplicate class bolts. 在模块 jetified-bolts-tasks-1.24.1.jar 中发现 AggregateException