断言(false)vs RuntimeException?

时间:2015-02-12 14:29:57

标签: java exception assert assertion

我正在阅读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;

我以前从未真正看过这种技术,也没有真正考虑过它,但我想这实际上意味着"这是无法访问的代码,不应该永远发生",无论发生什么事情都会崩溃应用程序。虽然技术上你可以用Throwable做到这一点,只要它没有被抓住。

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

2 个答案:

答案 0 :(得分:11)

最大的区别

assert false;

(不需要括号,assert不是函数,而是声明。)和

throw new RuntimeException();

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

  • 错误可能无法检测到
  • 控制流分析需要assert之后的虚拟throw new AssertionError("invalid type " + type); 语句(主要是混乱)。

因此,在上述情况下,我肯定会采用明确的(更简洁的)

assert

而不是return后跟虚拟type

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

答案 1 :(得分:1)

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

  

断言是Java编程语言中的一个语句   使您能够测试您对计划的假设。例如,   如果你写一个计算粒子速度的方法,你   可能会断言计算出的速度小于速度   光。

     

每个断言都包含一个你认为会有的布尔表达式   断言执行时为true。如果不是这样,系统会   抛出一个错误。通过验证布尔表达式确实是   确实,断言证实了你对行为的假设   你的计划,增加你对程序免费的信心   错误。

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