番石榴前提条件checkNull,checkArgument

时间:2012-10-09 17:01:40

标签: java guava

我想检查基类的前置条件,以便我知道子类型将始终使用有效的构造函数参数。

我们以一个构造函数为例:

  1. 需要2个或更多参数
  2. 采用不同类型的参数
  3. 对于一个参数,它执行多次检查(例如,String不为空不为空)
  4. 在这种情况下,如何最好地使用番石榴先决条件方法?

    在这样的模拟示例中:(这是做作的!)

    protected AbstractException(String errorMessage, Throwable errorCause) {
      super(errorMessage, errorCause);
      checkNotNull(errorMessage,
          ErrorMessage.MethodArgument.CANNOT_BE_NULL_CHECK, "errorMessage");
      checkArgument(!errorMessage.isEmpty(),
          ErrorMessage.MethodArgument.CANNOT_BE_EMPTY_STRING_CHECK,
          "errorMessage");
      checkNotNull(errorCause, ErrorMessage.MethodArgument.CANNOT_BE_NULL_CHECK,
          "errorCause");
    }
    

    我在检查参数之前最终调用super,因为对super的调用需要是方法的第一行,虽然我可以super(checkNoNull(errorMessage)),但是我不能这样做使用checkArgument进行相同的换行,因为它返回void。所以困境是:

    • 我在哪里对所有参数进行检查?我不想只为那个
    • 创建一个Builder
    • 如何在虚构的checkStringNotNullAndNotEmpty()
    • 中“分组”支票
    • 我是否应该考虑与匹配器框架集成? (hamcrest,fest断言......)

    我使用奇怪的ErrorMessage.MethodArgument.CANNOT_BE_NULL_CHECK,因为默认的throw不包含错误消息,所以从测试方面我不能将其识别为参数验证失败而不是“任何”NPE?

    我做错了吗?

1 个答案:

答案 0 :(得分:1)

这应该是一个评论,但它太长了。

  • 在测试之前调用super是无害的,只要超级ctor不执行它不应该做的事情
  • 可以通过静态构建器方法来防止,您不需要构建器。但这不值得。
  • 我怀疑分组测试通常有用;如果是的话,那么就会有这样的方法。但如果你需要一件这样一件具体的东西超过两次,那就写下你自己的;如果经常发生,请将其作为RFE报告给番石榴队。
  • 我很确定,匹配器在这里是一种矫枉过正,因为你只是创建一个例外,即很少使用的东西(我希望)。由于您的测试仅限运行时,无法真正帮助捕获错误。如果你可以静态地确保“正确”构造的异常,那将是很好的,但在纯java中它是不可能的。

更重要的是:你抛出的例外情况可能不如你没有进行所有检查所得到的情况。想象一下,用户提供原因而没有消息。你认为这很糟糕,但你用缺乏任何原因的NPE取而代之。那更糟。

看看Guava的Preconditions.format(包私有)。他们可以先检查正确的参数数量,但事实并非如此。您可以提供太少或太多,这是一个错误,但忽略它是处理它的最佳方式。