"assert false;" 是个好习惯吗?

Is "assert false;" a good practice?

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

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

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

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

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

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

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

我宁愿在调用函数时尝试检查函数的 return 值。

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

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

我个人认为 assert false 不是一个好的做法。

编辑

如果是要抛出的AssertionException,那你也可以这样用

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

所以你也可以这样处理

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

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

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

如果有一天你改变主意,不想让程序停止,你将能够捕捉到异常。

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

此外,您无法真正确定是什么抛出了您抓到的 exception/assertion。它 可能 在你期望的地方抛出,但它也可能在过滤代码中被抛出,例如 - 因此检查异常以检测 "not found" 情况可能会将其他问题与该案例混为一谈

另一种方法是使用 Optional(在 Guava 中存在类似的 class for pre-Java 8;或者您可以简单地使用 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.
}

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