【问题标题】:Is "assert false;" a good practice?是“断言错误”;一个好的做法?
【发布时间】:2016-04-07 06:13:11
【问题描述】:

我目前正在编写一个函数,根据给定的标准从列表中返回一个对象。它看起来像这样:

for (Object object : list) {
    if (condition(object)) {
        return object;
    }
}

这个函数应该总是从列表中返回一些东西,如果没有找到匹配的对象,这是一个错误的调用,一个严重的错误,程序应该停止。

因此,当我启用断言时,我在循环之后执行了以下操作:

assert false; // Will always trigger in debug mode.
return null; // No matter anyway, an AssertionException has already been thrown.

但我想知道我做得好不好?
如果没有,我应该怎么做?自己抛出异常?

无论如何,这种情况有什么规范吗?

【问题讨论】:

  • 看起来像是 stackoverflow.com/questions/28480068/… 的骗子,但我不想把我的单方面骗子锤子扔在上面......
  • 上下文和问题完全是另一回事,我认为您不需要扔锤子。 +1 让我在早上 8 点上班时嘲笑骗子锤子:D

标签: java error-handling assert


【解决方案1】:

我宁愿在调用时检查函数的返回值。

if (yourFunctionWithList(parameter) == null)
   //error handling, maybe throw new NPException or whatever. 
else
   //some object was returned

您也可以编写自己的异常类并以您想要的任何方式处理它。

我个人认为assert false 不是好习惯。

编辑

如果是关于将被抛出的AssertionException,那么你也可以像这样使用它

throw new AssertionError ("your error msg here");

所以你可以用同样的方式处理它

【讨论】:

  • 但是如果我从很多段代码中调用它呢?在函数结束时检查一次,而不是每次调用时检查一次不是更简单吗?
  • @yshavit 对,好久没用了。我这边的错误信息,添加了一个编辑
  • @Aracthor 特别是如果您多次调用它,您应该使用给出的语法以获得更详细的错误处理机会。但也许我没有得到错误的评论问题
  • 在我的方法中,您还可以通过创建一个虚拟对象来处理 null 以进一步处理(如果您需要默认值)
【解决方案2】:

断言或抛出异常的问题在于您需要使用异常处理来处理并非真正异常的情况。

此外,您无法确定是什么引发了您捕获的异常/断言。它可能在您期望的地方被抛出,但它也可能被抛出在过滤代码中,例如 - 因此检查异常以检测“未找到”情况可能会混淆其他问题用那种情况

另一种方法是使用Optional(Java 8 之前的 Guava 中存在一个类似的类;或者您可以简单地使用 Set<Object>,但这并不表示您期望正好是 0 或 1 值找到):

Optional<Object> method(List<?> list) {
  for (Object object : list) {
      if (condition(object)) {
          return Optional.of(object);
      }
  }
  return Optional.empty();
}

现在,在您的调用代码中,您明确知道您可能在列表中找不到项目:

Optional<Object> opt = method(list);
if (opt.isPresent()) {
  Object obj = opt.get();
  // Handle the fact it was found.
} else {
  // Handle the fact it wasn't found.
}

而不是您可能忘记添加的异常处理。

【讨论】:

    【解决方案3】:

    我个人不信任他们;它们通常在默认情况下被禁用,即使在开发环境中也是如此。这会使他们产生一种非常错误的安全感——静态分析工具和其他程序员都可能错误地认为它们按预期工作。

    【讨论】:

      【解决方案4】:

      你应该抛出一个异常,这是java中的正确方法:

      for (Object object : list) {
          if (condition(object)) {
              return object;
          }
      }
      throw new Exception('Failed: no matching item found!');
      

      如果有一天你改变主意并且不希望程序停止,你将能够捕获异常。

      【讨论】:

      • 可以捕获assert抛出的AssertionError。
      • 您可以为此使用IllegalStateExceptionIllegalArgumentException(取决于list 分别是实例变量还是方法参数)
      • @titogeo 但是您的方法没有得到 throws 签名,这会以某种方式使异常不可见且无关紧要:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-25
      • 2010-10-20
      • 1970-01-01
      • 1970-01-01
      • 2018-01-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多