断言(假)与 RuntimeException?

assert(false) vs RuntimeException?

我正在阅读 XWalkUIClientInternal 的源代码并将 运行 写入以下代码:

    switch(type) {
        case JAVASCRIPT_ALERT:
            return onJsAlert(view, url, message, result);
        case JAVASCRIPT_CONFIRM:
            return onJsConfirm(view, url, message, result);
        case JAVASCRIPT_PROMPT:
            return onJsPrompt(view, url, message, defaultValue, result);
        case JAVASCRIPT_BEFOREUNLOAD:
            // Reuse onJsConfirm to show the dialog.
            return onJsConfirm(view, url, message, result);
        default:
            break;
    }
    assert(false);
    return false;

我以前从未真正见过这种技术,也从未真正想过它,但我想这基本上意味着 "this is unreachable code and should not happen ever",无论如何都会使应用程序崩溃。尽管从技术上讲,您可以使用 Throwable 来做到这一点,只要它没有被捕获。

所以我的问题是,哪个更好,为什么,assert(false) 或扔 RuntimeException,或者 Error

Oracle guidelines (Programming with assertions) 之后,断言是为测试目的而设计的:

An assertion is a statement in the Java programming language that enables you to test your assumptions about your program. For example, if you write a method that calculates the speed of a particle, you might assert that the calculated speed is less than the speed of light.

Each assertion contains a boolean expression that you believe will be true when the assertion executes. If it is not true, the system will throw an error. By verifying that the boolean expression is indeed true, the assertion confirms your assumptions about the behavior of your program, increasing your confidence that the program is free of errors.

在您的示例中,开发人员假设代码永远不会到达 assert 语句。如果它很少发生,assert(false) 将抛出一个 Error(因为它永远不会到达那里)。这样做是为了测试目的。因此,纯粹出于测试目的使用断言。

最大的区别

assert false;

(不需要括号,assert不是函数而是语句。)和

throw new RuntimeException();

是可以禁用断言。实际上,默认情况下 禁用的,除非 JVM 以 -ea(“启用断言”)标志启动。如果启用断言,assert false 将无条件地抛出从 Error 派生的 AssertionError。但是由于可以禁用断言,因此存在两个问题,

  • 错误可能未被发现并且
  • 控制流分析需要在 assert 之后有一个伪 return 语句(主要是混乱)。

因此,在上述情况下,我当然会使用明确的(更简洁的)

throw new AssertionError("invalid type " + type);

而不是 assert 后跟一个虚拟 return

如评论中所述,这是假设 type 是内部参数,无效值表示逻辑本身存在错误。如果它是一个输入参数,它应该根据通常的规则进行验证,如果验证失败则抛出一个IllegalArgumentException