0

想象以下代码作为某个程序(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 程序员通常如何处理类似的情况。

任何关于异常的一般想法也感谢大家

4

2 回答 2

1

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

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

我不是编写 javadoc 的忠实拥护者,但有时您应该问自己:我能否用同一种语言(即技术语言、业务语言等)为这种方法及其异常编写好的 javadoc?如果 saveCustomerToDatabase() -Method 抛出 IOException,您将无法编写 javadoc。

于 2016-04-19T14:16:21.150 回答
0

如果您对 method 的当前设计感到满意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().");
    }
}
于 2016-04-19T14:11:55.253 回答