6

我有一个界面

public interface DataDAO {
     public void doSomething() throws Exception;
}

假设有两种实现,一种使用数据库获取数据,另一种使用 Web 服务。

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;
}

然后,当然相应地实施。

问题是,这有意义吗?我从来没有创建过自己的异常,所以我不确定这是否有意义。另外,创建 MyCoolException 时应该注意什么?

4

3 回答 3

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());
         }
    }
}
于 2013-05-16T05:27:00.533 回答
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(这几乎否定了整个观点)。

于 2013-05-16T05:20:17.283 回答
1

这有意义吗?

是的,它确实。通过声明会doSomething引发特定的已检查异常,您是在向方法的调用者发出信号,他们只需要捕获并处理该特定异常。通过声明 plain throws Exception,将鼓励调用者捕获并处理所有Exceptions,甚至包括运行时异常,例如NullPointerException.

创建 MyCoolException 时应该考虑什么?

它可以像下面这样简单:

public final class MyCoolException extends Exception {

    public MyCoolException(Throwable cause) {
        super(cause);
    }
}

因此,您的自定义异常将简单地充当原因异常的包装器,无论它可能是什么。如果可能,您可以添加一条包含可能有助于调试的附加信息的消息。当MyCoolException被捕获时,您可以通过调用解包它getCause(),或者将其传递给对日志框架的调用(它的堆栈跟踪将包括原因异常)。

于 2013-05-16T05:27:51.797 回答