Java 如何从try with resources捕获异常?

Java 如何从try with resources捕获异常?,java,try-catch,java-7,try-with-resources,Java,Try Catch,Java 7,Try With Resources,尽管try-with-resources特性本身可以处理自动关闭对象的所有功能,但我在最近的项目中遇到了一些特定的情况 我正在使用以下命令读取文件: try(InputStream=loader.getResourceAsStream(“remote config.xml”)) 问题是我读取上面文件的路径是错误的。因此,我期望异常为“FileNotFoundException”。现在,我知道在使用try-with-resources时,可以将catch块放在适当的位置,也可以不放在适当的位置。另

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

我正在使用以下命令读取文件:

try(InputStream=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;
    }
私有映射fillMappingsMap(映射服务到jndinamemappings)
{
ClassLoader=Thread.currentThread().getContextClassLoader();
try(InputStream=loader.getResourceAsStream(“remoting config.xml”))
{
if(流!=null)
{
//逻辑为-读取文件,填写要返回的映射。
}
}
捕获(IOException | ParserConfiguration异常| SAXE异常)
{
错误(“无法创建服务到JNDI名称映射。”,e);
}
返回serviceToJndiNameMappings;
}
如果不需要try-with-resources的catch块,那么为什么可以在那里添加它呢

如果自行车上不需要训练轮,为什么可以增加


回答:因为有时候有需要,有时候没有需要

在您的示例中,如果您需要处理由资源试用产生的异常,那么您可以添加一个
catch
来处理它。(如果需要,您甚至可以添加
最后一个
。)

(不管它值多少钱,你不必在经典的
try
…语句上有一个
catch
。你只需要一个
finally


当它不存在时,是否抛出任何异常

可能有。这取决于
try
的功能


在第二种情况下是否将异常抛出到JVM

异常不会“抛出到JVM”。那没有道理

但如果您询问是否可能抛出异常,那么是的,它们可能是。try块中的代码可能会引发未经检查的异常;e、 g.用“/…填充要返回的映射逻辑”表示的代码。注释

例如。。。如果有一个NPE错误,或者如果你在填充地图时填充了堆,得到了一个OOME


。。。我如何记录这些

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

就像您正常记录异常一样


你似乎对此感到担忧:

。。。我将错过一个非常重要的异常,即
FileNotFoundException
,它会让任何人感到恼火

你不会错过的:

  • FileNotFoundException
    IOException
    的一个子类,因此当您捕获
    IOException
    时,您肯定是在捕获它

  • 即使您没有捕获到
    IOException
    FileNotFoundException
    也是选中的异常。这意味着Java编译器将坚持您要么捕获它,要么在封闭方法中的“throws”子句中声明它

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

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


    另外,请阅读for
    ClassLoader.getResourceAsStream
    以了解它在找不到资源时的行为。
    getResourceAsStream
    仅当资源名称为
    null
    时才会抛出NullPointerException


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

    唯一的异常
    getResourceAsStream(name)
    可能抛出的是
    NullPointerException
    ,而且,当
    名称
    空时
    。即使找不到资源,它也不会引发任何其他异常


    如果您希望代码在资源丢失时引发
    FileNotFoundException
    ,那么使用
    newfileinputstream(String resourceName)
    (引发所需文件未找到异常)来加载资源,而不是
    getResourceAsStream()

    这是否回答了您的问题?某种程度上,但它具体指的是自动关闭对象上的关闭异常,而不是像FileNotFoundException这样的特定异常。无论如何,谢谢你。我也会看看。我知道这一点,只是当我无法捕捉到异常,它让我发疯。我不得不做很多令人恼火的手工工作。你确定抛出了
    FileNotFoundException
    ?因为
    catch
    子句将捕获异常,即使它不是由于
    close()
    引起的。最初,我尝试更改日志记录级别,认为它不会因此而被记录,但没有结果。所以,我试过了