3

我通常通过 Guava 的 Precondition 方法检查几乎所有的构造函数和公共方法参数。私有方法参数通常带有断言。但是,现在我正在考虑替换“内部”前提条件检查,即构造函数/工厂方法/通用方法(不是公共 API/应用程序 API 的一部分)中的检查......用断言,你怎么看? 也许这样会快一点,因为我有很多检查;-)

编辑:我的意思也是公共构造函数和工厂,它们不应该是公共 API 的一部分,只是在内部使用,例如:

/**
 * Constructor with both, complete and modifying page.
 * 
 * @param complete
 *          to be used as a base for this container
 * @param modifying
 *          to be used as a base for this container
 */
public NodePageContainer(final @Nonnull NodePage complete,
    final @Nonnull NodePage modifying) {
  assert complete != null;
  assert modifying != null;
  mComplete = complete;
  mModified = modifying;
}

在我拥有之前mComplete = checkNotNull(complete);......但它只是从另一个包中的一个类中调用,甚至不应该是公共 API 的一部分。如果 Java 允许降低此类类的可见性,那就太好了;-)

4

3 回答 3

7

断言和前提条件不是一回事。

断言检查不变量是否得到尊重:它检查自己的算法是否按预期工作。例如,随机生成器生成的数字始终为正数。一旦您检查了一切正常并且您没有断言失败,它们就可以被停用。

Guava 前置条件检查调用者没有传递无效参数或不调用不应调用的方法。例如,作为参数传递给nextInt()方法的限制大于 0,或者setSeed()在随机生成器启动后未调用。

如果您的目标是强制 API 的调用者尊重其合同,那么我将使用 Guava 前置条件,而不是断言。

于 2012-10-18T09:48:16.557 回答
3

根据Effective Java您的说法,应该对 API 公开的方法使用检查 ( Preconditions),对非 API 方法使用断言。这意味着任何不使用privatepackage private应该使用检查的方法/构造函数。WRT,private并且package private,使用断言更有效,建议在部署早期启用断言以帮助调试,然后随着信心的增长和性能成为问题,然后选择在生产周期的后期禁用它们。

于 2012-10-18T10:34:02.643 回答
0

我同意你的推理,但我会Precondition在你的例子中使用。构造函数从外面是可见的,所以你可以打赌总有一天有人会调用它。而且测试很便宜,所以不值得麻烦。

实际上,这是我的辅助标准:我主要根据 API / 非 API 原则来决定,但有时会为非常便宜或非常昂贵的检查例外(也取决于上下文和由于缺少检查而可能造成的伤害量)。

于 2012-10-18T14:52:10.667 回答