Java 如何从try with resources捕获异常?
尽管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(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异常和异常处理的许多困惑
另外,请阅读forClassLoader.getResourceAsStream
以了解它在找不到资源时的行为。getResourceAsStream
仅当资源名称为null
时才会抛出NullPointerException
因此,如果您尝试了getResourceAsStream(null)
,那么catch
块将捕获NullPointerException
(如果在该子句中提到)唯一的异常getResourceAsStream(name)
可能抛出的是NullPointerException
,而且,当名称
为空时
。即使找不到资源,它也不会引发任何其他异常
如果您希望代码在资源丢失时引发FileNotFoundException
,那么使用newfileinputstream(String resourceName)
(引发所需文件未找到异常)来加载资源,而不是getResourceAsStream()
这是否回答了您的问题?某种程度上,但它具体指的是自动关闭对象上的关闭异常,而不是像FileNotFoundException这样的特定异常。无论如何,谢谢你。我也会看看。我知道这一点,只是当我无法捕捉到异常,它让我发疯。我不得不做很多令人恼火的手工工作。你确定抛出了FileNotFoundException
?因为catch
子句将捕获异常,即使它不是由于close()
引起的。最初,我尝试更改日志记录级别,认为它不会因此而被记录,但没有结果。所以,我试过了