【问题标题】:How to add all available exceptions for an API to perform different action for different exception如何为 API 添加所有可用异常以针对不同异常执行不同操作
【发布时间】:2016-01-05 12:34:06
【问题描述】:

例如,假设我们要读取 XML 文件并读取 txt 文件。我怎样才能知道这些操作的所有可能异常,然后将它们添加到 catch 子句中,这样我的程序就不会意外中断? 一般情况下的方式如何?

编辑(对重复的回应): 我想知道一个动作的每个单独的例外是什么,而不是捕捉Exception,这样我就可以对它们中的每一个做出不同的反应。

【问题讨论】:

  • 如果读取涉及的操作有检查异常,那么你将不得不处理它们以解决编译时问题。你可以将它们添加到catch块中,最后你可以有异常..
  • @PrinceManiGupta 但可能存在不同类型的异常,例如字符串是否为空,或文件不存在等。所以我想针对不同的异常执行不同的操作。
  • 您也想处理运行时异常,即 NullPointerException??
  • @PrinceManiGupta 我想处理任何可能导致我的程序被中断的异常(通常),因为我想运行它并让它无人看管,所以它会在到达终点时停止.像这样。

标签: java xml file exception exception-handling


【解决方案1】:

首先要做的是尝试查找有关用于读取文本和 XML 文件的 API 的文档。 Javadoc 是记录 Java API 的内容,它将自动记录方法声明的所有异常。在大多数情况下,捕获这些异常就足够了。此外,请确保所有方法参数都正确,以免方法意外抛出 NullPointerExceptionIllegalArgumentException 或类似的东西。

如果您不了解已检查和未检查的异常,请立即阅读相关内容(例如 Checked vs Unchecked Exception)。简而言之,如果没有在throws 子句中声明,方法就不能抛出已检查异常,并且方法调用者必须要么捕获并处理异常,要么声明它抛出异常。没有throws 子句的方法只能抛出扩展RuntimeException 的异常,尽管有时程序员也会声明和/或记录这些异常。

确保您了解不同类型的异常。任何可投掷的东西都扩展Throwable(参见Throwable Javadoc)。 ErrorException 扩展可投掷。 Error throwables 通常是你不能做太多的事情,比如OutOfMemoryError,所以通常忽略这些是安全的。 Exceptions 是您所关心的。 RuntimeException 扩展 Exception,运行时异常未选中。任何其他扩展 Exception 的内容都被选中

IO 操作一般会抛出IOExceptionFileNotFoundExceptionSecurityExceptionIOException 被检查,并且由于 FileNotFoundException 扩展 IOException,它也被检查(仅捕获 IOException 将处理两者)。它们可以单独处理,但需要在IOException 之前捕获FileNotFoundExceptionSecurityException 未选中,除非代码在 JVM 中运行,使用安全管理器来限制程序,否则您不太可能看到它(文件权限拒绝访问可能会抛出 IOException)。

如果您不确定您的代码是否能够捕获所有异常并正确处理它们,那么您始终可以捕获 Exception 并进行处理。或者,您可以捕获Throwable,但您可能会忽略程序无法处理的错误,并且不会优雅地崩溃。如果您确实捕获了Throwable,那么最好使用它来捕获详细信息并优雅地崩溃,例如日志记录或 GUI 应用程序试图在从屏幕上消失之前显示错误。

最后,制定处理异常的计划。我经常看到的一个错误是捕获异常、打印和错误,然后由于 IO 资源未初始化而继续崩溃。如果方法不能完全恢复或正常崩溃,让它抛出异常。不要忘记您可以将信息附加到异常并使用异常链接,以便被调用者可以打印更有意义的错误。

例如,假设您的程序可以读取一些设置文件并逐行处理它。以下方法假定参数 fileName 已被检查,尽管您应该在 public 方法上显式检查参数并相应地抛出 NullPointerExceptionIllegalArgumentException

/**
 * Read a settings file and configure this object.
 * 
 * @param fileName Name of the file. Must not be <code>null</code>
 *   or empty.
 * 
 * @throws IOException If an IO error occurs while opening or
 *   reading the file.
 * @throws SecurityException If a security manager exists and its
 *   <code>checkRead()</code> method denies read access to the file.
 */
private void loadSettingsFile(String fileName)
        throws IOException, SecurityException {

    String line;  // Line read from file

    // Read file
    try (BufferedReader reader = new BufferedReader(new FileReader(new File(fileName)))) {

        while ((line = reader.readLine()) != null) {
            line = line.trim();

            // Do something with line
        }

    } catch (IOException ex) {
        throw new IOException("IO error reading settings file: " + ex.getMessage(), ex);

    } catch (SecurityException ex) {
        throw new SecurityException("Security error reading settings file: " + ex.getMessage(), ex);

    } catch (Exception ex) {
        throw new IOException(String.format("Unknown error reading settings file: %s: %s", fileName, ex.getMessage()), ex);
    }

    return;
}

在此示例中,SecurityExceptionIOException(也捕获 FileNotFoundException)被捕获,并生成了一个具有附加信息的相同类型的新异常,例如抛出异常时程序正在执行的操作.在新异常(构造函数的第二个参数)中包含原始异常会保留完整的堆栈跟踪(这是异常链接)。我知道当IOExceptionSecurityException在这段代码中抛出时,包含文件名;我不需要再次将其添加到异常中。当抛出其他异常时,它可能不会被包含在内,所以我在捕获Exception时明确这样做。

注意FileReader() 没有声明也没有记录SecurityException,但它确实抛出了它(在 OpenJDK 1.7.0_91 中验证)。这又回到了关于如何捕获所有异常的问题。有时它们没有记录,您必须根据经验进行猜测。从您不知道或不信任的代码中捕获Exception 也是一种选择。

在这个例子中,我选择将Exception 重新抛出为IOException,因为我的被调用者已经在处理这些。就风格而言,我更喜欢记录所有异常(甚至是未经检查的异常),所以这个判断调用对我来说是有意义的。

【讨论】:

    【解决方案2】:

    有很多方法可以处理这个问题。根据您的代码要求,您需要考虑如何处理不同的异常。下面的代码展示了如何分离出特定类型的异常,并在最后捕获剩余部分。

    try {
        // your code here that may throw lots of different exceptions
    } catch (AType1Exception ex) {
       // handle the AType1Exception specific exception here
    } catch (AType2Exception ex) {
       // handle the AType2Exception specific exception here
    } catch (Exception ex) {
       // handle all other exceptions here
    }
    

    如果您不需要处理特定类型的异常,而只需要一个通用处理程序来处理您可以使用的所有异常

    try {
        // your code here that may throw lots of different exceptions
    } catch (Exception ex) {
       // handle all exceptions here
    }
    

    有很多关于这个问题的文档参考,更多信息在这个链接Catch multiple exceptions at once?

    【讨论】:

    • 你没有明白问题的重点。 How 获取所有不同的异常?我知道如何添加 catch 子句,但我如何确定我已经参与了所有这些子句?
    • 当我说“你想如何处理不同的例外”时,我有点做了。
    • 正确的手来处理。
    【解决方案3】:

    哈哈,我能想到的唯一可能的解决方案是捕获 throwable,然后检查它与 java 中定义的每一种异常类型(已检查和运行时)和错误。

    它只会丢失您自己的基于 Throwable 的对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多