在任何编程论坛中发起宗教战争的简单方法是:“处理错误的最佳方法是什么?” :) 但这是一个完全有效的问题。
在 Java 中,您可能已经知道,有两种异常:运行时可检测和编译时可检测。 (另一组标签是“未检查”,用于运行时,“已检查”,用于编译时。)编译时可检测异常已抛出专门为它们定义的异常,就像您对自定义数据库异常所做的那样。已检查和未检查的异常(例如:空指针或索引超出范围异常)之间的最大区别在于,已检查的异常是需要在抛出时进行处理,或者使用“抛出”委派超出方法的范围" 关键字,强制调用方法处理它。可以处理未选中的(通过 try/catch 块),但这不是必需的。未经检查的异常也只抛出特定的异常,它们是 RuntimeException 类的后代,它本身是 Exception 的后代。 (请参阅http://docs.oracle.com/javase/7/docs/api/java/lang/RuntimeException.html 了解完整的低调)。虽然您可以使用 try/catch 块来捕获运行时异常,但您不能将这些类型的异常转变为由其特定运行时异常以外的任何东西处理(例如,运行时的空指针引用只能由 NullPointerException 对象处理或其超类对象之一,仅此而已)。
那么为什么要上“例外复习课”呢?因为一个异常是否应该被“向上”抛出给调用方法,或者在它发生的方法中就地处理,在很大程度上与异常生成代码之后的代码是否可以“生存”而没有成功完成 try/catch 块中的任何内容。后续代码本质上是否会留下可能的未检查(运行时)异常,例如空指针异常?很多时候,情况就是这样。或者,后续代码可能是可执行的,但处于不可靠状态(例如:未按需要设置的字段值等)。或者,在调用数据库进行更新时出现诸如 try/catch 块之类的情况,数据库数据状态可能与您想要完成的操作不正确。您需要根据上下文和目标(和依赖项)决定是否:
- 向上抛出异常而不在本地处理或报告它,实质上将负担交给调用方法来处理它。
- 在本地处理异常并记录/报告(可能),然后在 catch () {} 块中使用“return”退出方法。
- 在本地处理异常并记录/报告(可能),然后继续执行方法中的代码。
正如我所说,你做什么取决于你需要做什么。就个人而言,我认为异常处理是每个给定方法的问题,需要在本地处理。抛出异常实际上意味着该方法未能完成其预期任务——除非调用方法能够弥补其失败,或者在异常创建方法内,后续代码仍然可以完成预期目标。将它扔给调用方法只是意味着您取消了这两个选项之一,更糟糕的是,它在发生时立即被抛出,因此您取消了在异常之后拾取的任何选项在使用“return”退出该方法或继续该方法之前。现在有时可能需要使用 try/catch 来测试代码中的条件;即,使用某些方法的异常抛出特性来确定您的代码接下来会做什么。然而,这通常是不受欢迎的,尤其是。如果有“更清洁”的方式可用。 [没有像 Java 纯粹主义者这样的纯粹主义者。 :)]
当然,有时向上抛出异常是可以的。但是在 IMO 中,调用方法不需要太关心受调用方法逻辑影响的任何对象或数据的状态。我认为它是一种更简单的方式来处理出现的不太重要的异常。在我自己的情况下,我更喜欢在使用可能为空的对象之前检查空对象引用。由于方法中的异常而为可返回对象分配 null 值并在 catch () {} 块中返回它是一种非常常见的技术,用于让调用方法知道被调用方法未能完成它的意图.例如:
public meth1() {
Object o = meth2();
if (o != null) {
... do what you need to ...
} else
{
... deal w/ no valid o object ...
}
...
}
private Object meth2() {
Object retnme = new Object();
...
try {
... give it yer best ...
} catch ( Exception e )
{
logException(e); // a call to some logging method.
... clean up bad karma ...
return null;
}
...
return retnme;
}
所有这一切,关于您的代码的直接问题:基于上述内容并记住我不完全了解您的情况,我不明白您为什么应该将您创建的自定义异常抛出给调用方法,除非您出于某种原因特别想使用该异常向您要创建的数据库已经存在的调用方法发出信号。但是,如果知道这对调用方法没有特定用途 - 则无需这样做。这个决定的一部分取决于您是否希望使用任何实现您的接口的类来需要知道数据库是否存在。然而,避免使用这种策略的一种方法是编辑您的接口和类文件,以便该方法返回布尔值而不是 void。如果它返回“true”,则数据库已创建。如果“假”,则不是出于某种原因。您还可以让它返回一个 int 并根据它的值指示数据库创建是否成功。例如,值 0 可能表示成功,而值 1..n 可能表示失败原因,一个值当然表示 db 已经存在。
真的,天空才是极限。 :) 希望这对您有所帮助。