务实的程序员 - 断言式编程

The Pragmatic Programmer - Assertive programming

我正在阅读 The Pragmatic Programmer,在 A​​ssertive programming 部分,作者说:

Don’t use assertions in place of real error handling. Assertions check for things that should never happen: you don’t want to be writing code such as the following:

puts(​"Enter 'Y' or 'N': "​)
ans = gets[0] ​# Grab first character of response​
assert((ch == ​'Y'​) || (ch == ​'N'​))    ​# Very bad idea!​

我只期望两个值(Y/N),如果它收到一些其他输入,我想断言它并抛出错误。我想了解为什么 assert 方法是错误的,什么是更好的方法?

如果用户输入了无效的内容,您应该通过错误消息或警告让他们知道。由于用户的错误而故意导致崩溃永远不是一个好主意。

假设您正在编写一个简单的登录过程。如果用户输入的密码不正确,你是告诉他们密码不正确还是导致崩溃而不让他们知道原因?


正如您提供的源代码中所说,断言应该用于永远不会发生的事件,而且大多数情况下,如果事件最终发生,您的程序将无法从中恢复。应妥善处理与用户输入、网络、传感器数据等相关的错误。

另外正如@markspace 所提到的,断言通常 disabled/can 被禁用,因此永远不应在用户端使用它来代替任何类型的错误处理。

请查看Differences between Exception and Error

断言用于验证程序的逻辑。他们抛出 AssertionError,表明代码中存在错误。

要处理用户错误,您应该抛出异常,并进行适当的处​​理。如果用户输入无效,IllegalArgumentException 是合理的,但您可能更喜欢自己的异常层次结构。是否使用已检查或未检查的异常取决于您的偏好。

如果你想经常验证这个,你可能想要实现一个简单的验证库:

public static <T> void ensureValue(T value, T... legalValues) {
    if (!Arrays.asList(legalValues).contains(value)) {
        throw new IllegalArgumentException("Invalid value: " + value);
    }
}