【问题标题】:Exception handling within if statements in JavaJava中if语句中的异常处理
【发布时间】:2013-12-31 14:49:43
【问题描述】:

我是 Java 中自定义错误处理的相对新手,我正在尝试弄清楚如何使用 catch 语句在 if 语句中传递特定消息。我想在我完全想太多并且做得太过分之前,得到一些额外的眼睛来看看我正在尝试做的事情并提供反馈。

考虑: 我们有一个每小时日志文件的目录,我有一个按需报告作业,它创建了迄今为止创建的所有今天的日志文件的串联。我想添加一个检查级联日志文件是否存在的步骤,如果存在则删除它然后创建它,或者如果它不存在则只创建它。使用下面的代码,如果由于某种原因无法创建新文件,我将返回异常。

try {
   File file = new File (destinationPath + "todayToNowLogFile.csv");
   if(file.exists())
   {
      if(file.delete()) 
      {
      System.out.println(file.getName() + " is deleted!");
      } else {
      System.out.println("Existing file cannot be deleted.")
      } 
   } else {
      System.out.println("File will be created.");
   }
}
 //
catch(Exception e) {
   System.err.println("Exception: ");
   System.out.println("Exception: "+ e.getMessage().getClass().getName());
   e.printStackTrace();
}

现在,在无法删除文件的情况下,我想显示阻止文件删除的异常。首先,我需要catch 那个错误,然后我把try 放在哪里?

做这样的事情......

try 
{  
   if(file.delete()) 
   {
      System.out.println(file.getName() + " is deleted!");
   }
}
else {
   catch(Exception eDel) {
       System.err.println("Exception: ");
       System.out.println("Exception: "+ eDel.getMessage().getClass().getName());
       eDel.printStackTrace(); 
    }
}

....中断if...then 块。我不确定如何在if...then 中插入try...catch。有没有办法做到这一点?或者我的原始代码是否捕获了与try 块中定义的file 上的任何操作相关的每个错误,并且我需要将if...then 逻辑放入catch 块中,类似于此伪代码的行。 ...

catch(Exception e) {
   if(exception relates to file deletion) {
       "File delete exception " + exceptionMessages;
   } else if(exception relates to file creation) {
       "File create exception " + exceptionMessages;
   } else if(other exception) {
       "other exception " + exceptionMessage;
   } else {
       "no exceptions encountered"
   }
}

处理这种情况最合适的方法是什么?

【问题讨论】:

  • java.io.File#delete 仅在您无权删除文件时引发异常。如果您使用的是 Java 7,请考虑改用 java.nio.file.Files#delete,因为它会针对更多情况抛出更详细的异常。
  • 你把它放在if 块中,就像任何其他块一样,例如,另一个if
  • 您真正想要的是创建您的自定义异常。请参阅下面的我的回复。

标签: java error-handling


【解决方案1】:

你想要在这里创建你自己的异常类。

要创建一个异常类说你需要扩展异常类。这是一个例子。 假设我的自定义异常类应该命名为MyFileErrorException

所以我创建了一个这样的新类 -

class MyFileErrorException extends Exception {

    private String message = null;

    public MyFileErrorException() {
        super();
    }

    public MyFileErrorException(String message) {
        super(message);
        this.message = message;
    }

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

    @Override
    public String toString() {
        return message;
    }

    @Override
    public String getMessage() {
        return message;
    }
}

现在我需要随意抛出这个异常。因此,在您的情况下,您想捕获文件删除异常,因此代码将像这样-

if(file.delete()) 
      {
      System.out.println(file.getName() + " is deleted!");
      } else {
      try{
            System.out.println("Existing file cannot be deleted.")
            throw new MyFileErrorException("File Could not be deleted val is null");
      }catch(MyFileErrorException ex){

        //Do wahtever you want to do
      }

      } 

【讨论】:

    【解决方案2】:

    您应该将try/catch 视为任何其他声明。所以你可以把它放在if/then/else 语句的两个分支中的任何一个中,但它必须是完整的:

    if(statement){
        ...    
        try{
            ...
        }catch(...){
        ...
        }
        ...
    }else{
        ...    
        try{
            ...
        }catch(...){
        ...
        }
        ...
    }
    

    如果您必须捕获多个异常,您可以通过多个捕获部分来实现:

        try{
            ...
        }catch(Exception1 e1){
        ...
        }catch(Exception2 e2){
        ...
        }catch(Exception3 e3){
        ...
        }
    

    【讨论】:

      【解决方案3】:

      首先你应该检查是否有任何方法可以抛出任何特定的异常。您可以通过查看 Javadoc 或使用您最喜欢的 IDE 来做到这一点。

      如果您将 Exception 作为 Exception 类捕获,它会捕获它的子类的每个 Exception。

      如果您想进行特定的异常处理,例如对于 delete() 方法中的 IOException,您可以捕获每个特定的 Exceptionclass 或在 Java 7 中使用 multi-catch

      try {
      
          do regular code that can throw exceptions
      
      } catch(Exception e) {
          it catches every Exception that is a subclass of Exception.
          You handle every exception raised in the try block above by the same way
      }
      

      如果您想以不同的方式处理异常,例如打印不同的消息,就像下面的例子一样:

      try {
          do sth
      } catch (SpecificExceptionclass sec) {
          do sth specific for this exception
      } catch (AnotherExceptionClass aec) {
          do sth else
      }
      

      如果您想对某些特定异常类进行相同的异常处理,或者只使用 Java 7 中的 Multicatch:

      try {
          do sth
      } catch (SpecificExceptionclass | AnotherExceptionClass e) {
          do sth specific for this exception
      }
      

      要实现代码中抛出的不同异常,方法至少应该抛出不同的异常。在您使用 file.exists() 和 file.delete() 的示例中,您的代码仅抛出一个 IOException,因此没有使用特定的异常处理。

      【讨论】:

        【解决方案4】:

        我认为将代码放入返回 true 或 false 的函数中是个好主意。

        1:True 表示文件不存在且已创建
        2:False 表示文件存在并被删除。
        3:文件存在但不能删除的异常。

        还提供了一个单独的函数来判断文件是否存在。

        您的函数顶部的 javadoc 应该解释上述内容,这样函数的调用者就不必查看它们的内容来确定如何使用它们。

        注意异常是一个不寻常的事件,不应该被抛出来指示插入/删除的状态。它应该保留给调用者通常不会遇到的异常情况。

        关于例外的说明:如果您有一个包含 1000 个类的大型项目,每个类平均有 20 个函数,那就是 20000 个函数。对每个函数进行过多的异常处理(例如检查作为参数传入的空值)是不切实际的。解决这个问题的方法是在 java 语言 (FileIO) 中处理已检查的异常,并让(大量)未检查的异常在函数调用链中产生涟漪,直到您离开所有业务逻辑并即将显示结果。仅当您想在重新抛出异常之前向异常添加其他信息时才捕获它们。示例:添加正在抛出的 SQLExeption 记录的主键值,以便您了解导致问题的记录。在返回给用户之前,记录堆栈跟踪并向用户显示一条简化消息(不是堆栈跟踪)。函数的调用者应该阅读它的 javadoc 以了解如何使用它。如果他违反了您的 javadoc,该函数可能会或可能不会抛出异常。遵循 javadoc 是他的责任。最后一点:您的项目应该有整个项目的通用编码策略,以防止调用者意外引入某些类型的异常,例如:所有函数都不会接收空值作为参数或将返回空值,除非在其 javadoc 中指定.除非在其 javadoc 中指定,否则所有函数都将正确接受空列表或空字符串作为参数(或返回)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-04-21
          • 1970-01-01
          • 2014-02-15
          • 1970-01-01
          • 1970-01-01
          • 2013-03-15
          • 2014-10-24
          • 1970-01-01
          相关资源
          最近更新 更多