从getter返回之前检查null是不好的习惯吗?



我想防止getters返回零值,例如示例Bellow。这是一个不好的做法吗?

示例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,然后设计您的实现以适应。这些设计的最佳实践之一是,返回Collection时,您不应将特殊情况"零元素"归入null中。也就是说,如果您的方法可以合理地返回一个空集合,则它应该返回一个空的集合,而不是像null这样的特殊值。这几乎总是简化客户端代码并删除整个类潜在的NPE。这并不意味着您不能内部使用null来标记"零元素",但这意味着如果您这样做,则应在返回时执行转换(如示例中)。

因此,如果您的getTasks()方法指定它始终返回(可能为空的)列表,则使用null检查,如示例中是合理的实现选择。在您的具体示例中,这可能不是最佳选择,因为JDK提供了Collections.emptyList<T>()之类的方法,它使您可以便宜地重复使用单顿列表实例,因此您不会将任何内容保存在内存中,并且CPU节省值得怀疑<<sup> 1 。

此外,通过使用" null表示空列表"约定,您需要所有内部方法必须检查tasks == null,或者使用GetTasks()方法。在收集对象的特定情况下,我通常更喜欢使用Collections.empty*方法而不是NULL表示空列表 2 。由于Integer.valueOf(0)返回所有合规JVM上的单例对象,因此适用于Integer情况。

除了那些特定的情况外,当然有理由使用空检查来表示缺失或默认元素,尤其是当没有良好的"空"元素出现自己或表现重要的地方时。您会发现这种模式在设计良好的库中经常使用,例如Java Runtime和Guava。因此,您不能说这是一种不好的做法。要仔细评估。

是一种习惯。

1 使用这些Collection.empty*方法也适用于您的示例。在无效情况下,您可以考虑直接返回Collections.emptyList(),而不是创建新的ArrayList按需。这是否适当取决于总体设计,例如该列表是否可变。

2 Collections.emptyList()是否比显式空检查更快,实际上是一个复杂的问题。如果空列表非常罕见,以至于通常不会在给定的过程中出现,则emptyList()方法的速度可能更快,因为由于空列表的频率为零,因此其成本(wrt the Getter)将变为零。另一方面,当确实出现空列表时,它可能会为使用List的所有方法创建一个多态性调用站点:每个这样的网站都可能看到一个特殊的"空列表"实现和ArrayList。这可以减慢代码,尽管很大程度上取决于内部决策。因此,像往常一样,与绩效有关,确切的答案很复杂,如果细节很重要,则需要介绍。

一般而言,,这是不良练习。

例如,如果对象的值(在这种情况下为整数)是真正的null,则API用户期望返回null。不是0。例如,您API的用户也许将0视为动作,而null可能会解释为意味着从未发生过。)

例如2,API用户不会指望Getter具有这样的副作用,例如构建新列表。

除非您在方法的合同(Javadoc)中包括这些行为,否则不能期望用户意识到实际发生了什么,这可能会导致他们使用不正确的数据。相反,他们应该期望 null可以来自这些方法,并自行检查。

您可以通过使用诸如javax.annotation.Nullablejavax.annotation.Nonnull之类的注释来帮助他们,以暗示用户(及其IDES)分别可以或不能为null。这样,他们就可以明智地预期和对方法结果的无效性做出反应。

警告:正如罗伯特在答案中所说的那样,在某些情况下,懒惰的负载是有道理的。但是它必须仔细完成,并且只有在有意义的情况下才能进行。约书亚·布洛赫(Joshua Bloch)在他的书《有效的爪哇》,第二版中写了一个有关懒惰初始化的子章,他解释说,懒惰的初始化应进行"明智地" ,并有效地称其为预选前。

您所描述的是一种设计模式,称为懒惰加载(https://en.wikipedia.org/wiki/lazy_loading)。如果在某些情况下使用,这是一个很好的做法,但不是治愈的方法,也不是为了娱乐。

相关内容

  • 没有找到相关文章

最新更新