链接异常,捕获异常以抛出新异常

时间:2016-04-19 14:05:07

标签: java exception exception-handling checked-exceptions

想象一下以下代码作为某个程序(java)的一部分:

function z(){
try{
  //some code here, that might throw exceptions.
}catch (SomeException | SomeOtherException e){
  //some exception handling here.
}

function y(){
  z();
}

function x(){
  y();
}

并且假设如果在函数z中抛出异常SomeException或SomeOtherException,则函数x和y不会按预期执行。 我们想编写代码,使函数x和y知道函数z中抛出了异常,并使它们相应地起作用。 什么是最好的方法呢?

function z() thrown FunctionZFailedException{
  try{
    //some code here, that might throw exceptions.
  }catch (SomeException | SomeOtherException e){
    throw new FunctionZFailedException();
  }
}

function y() throws FunctionYFailedException{
  try{
    z();
  }catch (FunctionZFailedException e){
    throw new FunctionYFailedException();
  }
}

function x(){
  try{
    y();
  }catch (FunctionYFailedException e){
   //Do something, like alerting user that something went wrong.
  }
}

这是否太过分了,即宣布新例外的唯一目的是"转发"更高级别的其他例外?

我认为我们也可以让SomeException和SomeOtherException飞起来并在函数x中捕获它们。但imo可能会弥补不太可读的代码,

例如,如果函数z中捕获的异常是SQLException和NoSuchAlgorithmException,则函数y是login()函数。然后函数x将尝试调用login(),并捕获一个SQLException | NoSuchAlgorithmException,如果让那些异常简单地飞到最高级别,或者捕获LoginFailedException,如果我们立即捕获每个异常,并让它们抛出新的异常。看起来像捕获LoginFailedException会使代码更易读。

Imo两种方式都有它们的缺点(代码不太可读而不是引入许多异常),我想知道类似的情况通常由经验丰富的java程序员处理。

关于例外的任何一般想法也赞赏感谢你们

2 个答案:

答案 0 :(得分:1)

当您查看代码(以及方法和异常的名称)时,请查明方法及其抛出的异常是否在同一个抽象级别上。

如果你有一个getInputStream()方法,那么相应的异常就是IOException。如果在getDatabaseConnection()中调用该方法,则应捕获IOException并抛出SQLException。如果你的saveCustomerToDatabase()方法需要这个方法,那么你应该抛出类似ProcessFailedException的东西。

我不是写javadocs的忠实粉丝,但有时候你应该问问自己:我是否能够为这种方法编写好的javadoc及其在同一种语言中的异常(即技术语言,商业语言等) 。)?如果它抛出IOException,您将无法为saveCustomerToDatabase()-Method编写javadoc。

答案 1 :(得分:0)

如果您对方法z()的当前设计感到满意,并且您希望方法y()x()到"知道"在z()发生了一些不好的事情,那么你可以在吞下它之后让z()重新抛出异常。

public void z() {
    try {
        // some code here, that might throw exceptions.
    } catch (SomeException | SomeOtherException e) {
        // handle the exception and then rethrow it
        logger.log("An exception happened in z().");
        throw e;
    }
}

public void y() {
    try {
        z();
    } catch(Exception e) {
        // handle problem with z() and rethrow the exception
        logger.log("An exception happened when calling z().");
        throw e;
    }
}

public void x() {
    try {
        y();
    } catch(Exception e) {
        // handle problem with y()
        logger.log("An exception happened when calling y().");
    }
}