问题描述
尽管 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
,它可能会让任何人感到恼火。
你不会错过的:
-
FileNotFoundException
是FileNotFoundException
的子类,因此当您捕获IOException
时,您肯定会捕获它。 -
即使您没有捕捉到
IOException
,IOException
也是一个检查异常。这意味着 Java 编译器会坚持要求您捕获它,或者在封闭方法的“throws”子句中声明它。 -
最后
FileNotFoundException
无论如何都不会抛出loader.getResourceAsStream("remote-config.xml")
!它不是打开文件。它正在获取资源的输入流。如果找不到资源,FileNotFoundException
调用将返回getResourceAsStream
而不是抛出异常。
我建议您阅读 Oracle Java 教程中的 Catch or Specify 页。它将解答您对 Java 异常和异常处理的许多困惑。
此外,请阅读 null
的 javadocs 以了解它在找不到资源时的行为。
仅当资源名称为 getResourceAsStream
时,null
才会抛出 NullPointerException。
因此,如果您尝试过 getResourceAsStream(null)
,那么 catch
块将捕获 NullPointerException
(如果在子句中提到)
唯一可能抛出的异常 getResourceAsStream(name)
是 NullPointerException
,当 name
为 null
时也是如此。即使找不到资源也不会抛出任何其他异常。
如果你希望你的代码在资源丢失时抛出一个 FileNotFoundException
,那么使用 new FileInputStream(String resourceName)
(它会抛出所需的文件未找到异常)来加载你的资源而不是 getResourceAsStream()