异常处理问题

时间:2010-12-28 14:40:35

标签: java exception-handling coding-style

我注意到许多开发人员正在使用实用程序类执行所有类型的检查,我的意思是,例如,SomeDefenseClass.checkState(arg > 4)等等。它似乎是非常好的和干净的方式来检查参数,应用程序状态,空指针等。利用它可以只抛出IllegalStateException进行状态检查。 NPE表示空指针等。但我现在面临一个问题:我必须为不同类型的非法国家提出许多不同的例外,例如: ItemNotFoundException,UserNotAuthorizedException等等..

所以我可以为这个问题考虑三个解决方案,但不幸的是,似乎没有人足够好

1)最简单的方法:根本不使用实用程序类,只写块。 (只是不喜欢这么多

if (!foo) {
    throw new SomeException(arg1); 
}
if (!bar) {
    throw new SomeOtherException(arg1, arg2);
}
// and so on

2)为每个可能的异常写一个不同的stateCheck方法(不太好,因为我们有大约30个不同的例外和计数)

3)将一种方法写入防御类:

public static void checkState(boolean condition, Throwable t) {
    if (!condition) {
        throw t;
    }
}

无论如何,在这种情况下,我必须在每次执行状态检查时创建新的Exception对象,这意味着创建了数千个完全不必要的对象,并且在一天结束时它可能会成为问题:)

那么,有人可以为这个问题推荐一个好的解决方案吗?

谢谢

3 个答案:

答案 0 :(得分:3)

通过阅读您的第一段,我感觉您正在尝试将业务异常(ItemNotFoundException,UserNotAuthorizedException)与类级别断言(检查参数,应用程序状态,空指针)混合在一起。

业务异常就像是API的合同,应该对业务有意义。最好从它们所属的位置创建并抛出它们。这不仅是一个很好的封装,而且保留了正确的堆栈跟踪,从而有助于更轻松地调试问题。

断言主要用于内部逻辑验证,并且在测试周期的早期比在生产中找到逻辑错误,开发人员错误等。理想情况下,断言在开发和测试时打开,在生产中关闭。前提条件,后置条件和不变量是3种断言类别。详细了解Design By Contract

没有必要将断言检查移动到实用程序方法。计划使用Java的内置assert keyword并在开发和测试期间启用它们。我的建议是对不变量和后置条件检查使用assert关键字,并使用google-guava's Preconditions检查前置条件。

如果您发现在多个位置执行了常见验证,那么最好将它们封装到自己的类中,例如: AgeValidator,SalaryVaidator等(DRY原则)。同样不需要在这里构建自己的框架,使用标准的java规范JSR 303 Bean Validation

答案 1 :(得分:1)

我讨厌实用这些检查的实用程序类的想法。

我的第一个想法是“将合同执行保留在需要它的对象中”。使用实用程序类可以提供重用的经济性。

我的第二个想法是绑定和验证框架,就像Spring一样。将UI中的输入绑定到对象中,验证它并继续前进。这似乎对我来说更可重复;春天就是证据。

答案 2 :(得分:0)

考虑OVal或类似的框架