在这种特定场景中,断言是否比例外更合适?
据我了解,当程序FUBAR达到无法恢复并退出的程度时,应使用断言。
我还被告知要为了清晰度和错误消息处理而抛出异常。
每次使用时间之间是否存在细微差别?是否有一个例子,必须无条件地使用断言代替例外?
public void subscribe(DataConsumer c) throws IllegalArgumentException {
if (c == null) {
// Almost certainly FUBAR
throw new IllegalArgumentException("Can't subscribe null as a DataConsumer. Object not initialized");
}
if (dataConsumerList == null) {
// Definetely FUBAR
throw new IllegalArgumentException("Nothing to subscribe to. DataConsumerList is null");
}
dataConsumerList.add(c);
}
答案 0 :(得分:4)
就我个人而言,我并不热衷于为这类事情使用断言,因为它们可以被关闭。有些地方在运行测试时使用断言,但为了速度而禁用它们进行生产。对我来说,这就像正常驾驶考试一样,但是当你上高速公路时,你可以取下安全带。
当然,断言只会抛出异常。如果您绝对想立即 ,那么您需要使用Runtime.halt
之类的内容。
所以我喜欢这里的异常,虽然我给出一个空参数时通常使用NullPointerException
,如果dataConsumerList
是你的状态的一部分然后我会亲自使用IllegalStateException
来区分这种情况。 (遗憾的是,Java没有与.NET相同的ArgmentNullException
,考虑到它的常见检查。)
Guava有一个有用的Preconditions
类,可以让你更简洁地写出来:
public void subscribe(DataConsumer c) throws IllegalArgumentException {
Preconditions.checkNotNull(c,
"Can't subscribe null as a DataConsumer. Object not initialized");
Preconditions.checkState(dataConsumerList != null,
"Nothing to subscribe to. DataConsumerList is null");
dataConsumerList.add(c);
}
答案 1 :(得分:1)
一般规则(从here复制)
断言应该保护(不总是明显的)错误 开发者,例如尽管它是NULL,但使用指针。
异常是一种处理可能合法发生的错误的方法 运行时,例如尝试连接到某个服务器的失败(可能 因各种原因没有回应。)
使用google-guava Preconditions.checkNotNull()类编写上述代码有更好的方法。
public void subscribe(DataConsumer c) throws IllegalArgumentException
{
checkNotNull(c, "Can't subscribe null as a DataConsumer. Object not initialized");
checkNotNull(dataConsumerList , "Nothing to subscribe to. DataConsumerList is null");
dataConsumerList.add(c);
}
答案 2 :(得分:0)
如果您可以用英语表达,请使用assert作为“gotta”(Got to,Must)和“otta”的例外(应该是,应该)。
将断言用于显示停止,关键条件必须为true才能继续执行。示例可能是分区正确发生(想想英特尔芯片浮点错误)或者在正确打开它之后数据库连接不为空。如果发生了这些,则程序执行不应继续。
使用throw来解决您的方法可能遇到的可预见错误。抛出是合同的一部分,向您和其他程序员声明可能遇到某些类型的错误(而且这不是您的责任)。
在您的示例中,我的猜测是在正常情况下永远不会发生空消费者或空列表。如果我的猜测是正确的,那么你会想在这里使用一个断言,声明subscribe()将处理它。
如果我的猜测是错误的并且发生了一个空的消费者,比如50次中的1次,则抛出会更好,你会声明subscribe()与调用方法形成一个契约,其中调用方法处理错误。
答案 3 :(得分:0)