我有一个界面
public interface DataDAO {
public void doSomething() throws Exception;
}
让我们说有两个实现,一个使用Database来获取数据,另一个使用Webservice。
public class DataDAOJdbc implements DataDAO {
public void doSomething() throws Exception {
//Implement
}
}
public class DataDAOWebService implements DataDAO {
public void doSomething() throws Exception {
//Implement
}
}
正如您已经看到的,问题是启动了超级通用异常。因为这两种实现都需要引发同样的异常。
Jdbc实现实际上只引发了SQLException,而Webservice实现只会提升IOException。
问题是,如何让界面更优雅,所以我捕获了一个正确的异常?
我首先要创建自己的异常,并在接口级别声明它
public interface DataDAO {
public void doSomething() throws MyCoolException;
}
然后,当然,实施accinly。
问题是,这有意义吗?我从来没有创建过我自己的异常,所以我不确定这是否有意义。另外,在创建MyCoolException时我应该考虑什么?
答案 0 :(得分:4)
我首先要创建自己的异常,并在接口级别声明它(...)这有意义吗?
是的,它确实有意义,我认为这是处理这些情况的最佳方式。
我将为此提供一个启动示例(基于您当前的代码):
public class MyCoolException extends Exception {
public MyCoolException() {
}
public MyCoolException(String message) {
this.message = message;
}
}
public interface DataDAO {
public void doSomething() throws MyCoolException;
}
public class DataDAOJdbc implements DataDAO {
public void doSomething() throws MyCoolException {
//Implement
try {
} catch (SQLException e) {
//handle the exception
logger.error("Error!", e);
//throw your custom exception
throw new MyCoolException(e.getMessage());
}
}
}
public class DataDAOWebService implements DataDAO {
public void doSomething() throws MyCoolException {
//Implement
try {
} catch (IOException e) {
//handle the exception
logger.error("Error!", e);
//throw your custom exception
throw new MyCoolException(e.getMessage());
}
}
}
答案 1 :(得分:2)
您可以使用泛型类型来定义抛出的接口:
public interface DataDAO<E extends Throwable> {
public void doSomething() throws E;
}
然后您的实现将如下所示:
public class DataDAOJdbc implements DataDAO<JDBCException> {
public void doSomething() throws JDBCException {
//Implement
}
}
public class DataDAOWebService implements DataDAO<WebServiceException> {
public void doSomething() throws WebServiceException {
//Implement
}
}
然而,这有一个缺点,你不能再以同样的方式处理所有异常,除非你只是抓住Exception
(这几乎否定了整个点)。
答案 2 :(得分:1)
这有意义吗?
是的,确实如此。通过声明doSomething
抛出特定的已检查异常,您向调用者发出信号,告知他们只需要捕获并处理该特定异常。通过声明普通throws Exception
,将鼓励调用者捕获并处理所有Exception
,甚至包括NullPointerException
等运行时异常。
创建MyCoolException时应该考虑什么?
可能如下所示:
public final class MyCoolException extends Exception {
public MyCoolException(Throwable cause) {
super(cause);
}
}
因此,您的自定义异常只会充当原因异常的包装器,无论它是什么。如果可能,您可以添加一条消息,其中包含可能有助于调试的其他信息。当MyCoolException
被捕获时,您可以通过调用getCause()
来解包它,或者将其传递给对日志框架的调用(其堆栈跟踪将包括原因异常)。