“assert false;”是一种好的实践吗?

4

我目前正在编写一个函数,根据给定的条件从列表中返回一个对象。代码如下:

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.

但是我在想我做得对还是不对?
如果不对,我该做什么呢?自己抛出异常吗?

无论如何,在这种情况下是否有任何规范呢?


2
看起来像是 https://dev59.com/M4fca4cB1Zd3GeqPns75 的重复,但我不想对此进行单方面的判断。 - yshavit
1
这个上下文完全不同,问题也是如此,我认为你不需要扔你的锤子。+1 让我在上班时间早上8点笑出声来,谢谢你的“重复锤” :D - Do Re
4个回答

5

在调用函数时,我更愿意尝试检查其返回值。

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");

所以您可以以同样的方式处理它。

但是如果我从许多代码片段中调用它呢?难道在每次调用时都检查它不如在函数结束时一次性检查它简单吗? - Aracthor
1
@yshavit 对,我很久没用过它们了。是我的错误信息,我已经添加了编辑。 - Do Re
@Aracthor 特别是如果您多次调用它,应使用给定的语法以获得更详细的错误处理机会。但也许我没有理解评论问题。 - Do Re
在我的方法中,您还可以通过创建一个虚拟对象来处理空值(如果您需要默认值)以便进一步操作。 - Do Re

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.
}

与其处理异常,你可能会忘记添加处理代码。

1

在Java中,您应该抛出一个异常,这是正确的方式:

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

如果有一天你改变主意,不想让程序停止,你可以捕获异常。

2
你可以捕获由assert抛出的AssertionError。 - titogeo
你可以使用IllegalStateExceptionIllegalArgumentException来处理这个问题(具体取决于list是实例变量还是方法参数)。 - Erwin Bolwidt
@titogeo 但是你的方法没有得到一个throws签名,这样异常就会变得看不见和无关紧要 :) - Ji aSH

1

我个人不太信任它们;它们通常在开发环境中默认禁用。这可能会给人一种非常错误的安全感 - 静态分析工具和其他程序员可能会错误地认为它们按预期工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接