如何从 try-with-resources 中捕获异常?

问题描述

尽管 try-with-resources 功能本身可以处理 AutoClosable 对象的所有功能,但我在最近的项目中遇到了一些特定情况。

我正在使用以下文件读取文件

try(InputStream stream = loader.getResourceAsstream("remote-config.xml"))

问题是我读取上述文件的路径错误。因此,我预计会出现“FileNotFoundException”异常。现在,我知道当我使用 try-with-resources 时,我可以在适当的位置设置 catch 块,而不是在适当的位置。此外,令我惊讶的是,我的 catch 块没有捕获任何异常,日志中也没有出现任何错误

如果不需要那个带有 try-with-resources 的 catch 块,那为什么要在那里添加它呢?而且,当它不存在时,是否会抛出任何异常?在第二种情况下是否向 JVM 抛出了异常,我该如何记录这些异常?

下面是我的代码

    private Map<String,String> fillMappingsMap(Map<String,String> servicetoJndiNameMappings)
    {
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        try(InputStream stream = loader.getResourceAsstream("remoting-config.xml"))
        {
            if (stream != null)
            {
                // logic for - read the file,fill the map to be returned.
            }
        }
        catch (IOException | ParserConfigurationException | SAXException e)
        {
            logger.error("Could not create service to JNDI Name mapping.",e);
        }
        return servicetoJndiNameMappings;
    }

解决方法

如果不需要那个带有 try-with-resources 的 catch 块,那为什么要在那里添加它?

如果自行车上不需要辅助轮,为什么要加?

答案:因为有时需要,而有时不需要。

在您的示例中,如果您需要处理源自 try with resources 的异常,那么您可以添加一个 catch 来处理它。 (如果需要,您甚至可以添加 finally。)

(就其价值而言,您不必必须在经典的 catch ... 语句中使用 try。您可以只使用 { {1}}。)


而且,当它不存在时,是否会抛出任何异常?

可以有。这取决于 finally 的作用。


是否是第二种情况下抛出到JVM的异常...

不会向“JVM”抛出异常。这没有意义。

但是如果您问是否可能会抛出异常,那么是的,它们可能会抛出。 try 块中的代码可能会抛出未经检查的异常;例如您由“// ...填充要返回的逻辑的地图”指示的代码。评论。

例如……如果存在 NPE 错误,或者您在填充地图时填充了堆并得到了 OOME。


...我该如何记录这些?

我怀疑在那里记录异常是否是个好主意。但是你可以通过捕获它们、记录它们然后重新抛出它们来做到这一点。

与您正常记录异常一样...


您似乎对此很担心:

...我将错过一个非常重要的例外,即 try,它可能会让任何人感到恼火。

你不会错过的:

  1. FileNotFoundExceptionFileNotFoundException 的子类,因此当您捕获 IOException 时,您肯定会捕获它。

  2. 即使您没有捕捉到 IOExceptionIOException 也是一个检查异常。这意味着 Java 编译器会坚持要求您捕获它,或者在封闭方法的“throws”子句中声明它。

  3. 最后FileNotFoundException无论如何都不会抛出loader.getResourceAsStream("remote-config.xml")!它不是打开文件。它正在获取资源的输入流。如果找不到资源,FileNotFoundException 调用将返回 getResourceAsStream 而不是抛出异常。

我建议您阅读 Oracle Java 教程中的 Catch or Specify 页。它将解答您对 Java 异常和异常处理的许多困惑。

此外,请阅读 nulljavadocs 以了解它在找不到资源时的行为。

,

仅当资源名称为 getResourceAsStream 时,null 才会抛出 NullPointerException。

因此,如果您尝试过 getResourceAsStream(null),那么 catch 块将捕获 NullPointerException(如果在子句中提到)

,

唯一可能抛出的异常 getResourceAsStream(name)NullPointerException,当 namenull 时也是如此。即使找不到资源也不会抛出任何其他异常。

如果你希望你的代码在资源丢失时抛出一个 FileNotFoundException,那么使用 new FileInputStream(String resourceName)(它会抛出所需的文件未找到异常)来加载你的资源而不是 getResourceAsStream()