[英]Throwing both main exception and sub-type, is there a proper way?
好的,所以我在SO和程序员之间有很多与异常相关的问题,但是有太多问题要问,或者我不知道要输入什么,或者问的人不多。
因此,假设我有一个抛出FileNotFoundException
(FNFE)的方法。 然后,我有了另一个使用第一个方法的方法,但是还会抛出IOException
(IOE)。
我的处理程序可以同时捕获这两者,并且各自执行不同的操作,但是我的IDE(IntelliJ)发出信号,表明我“在抛出列表中已有一个更通用的异常'java.io.IOException'”。
我知道这样做是可行的:
public File openOrCreate(String pathStr) throws FileNotFoundException,
IOException {
try {
// Method that generates the FNFE
Path path = ReposioryProposition.getPath(pathStr);
File file = path.toFile();
catch (FileNotFoundException fnfe) {
throw fnfe;
}
if (!file.exists())
file.createNewFile(); // IOE
return file;
}
但是我需要明确地做吗? 它是否可以在没有显式版本的情况下工作,或更危险的是, 有时会在没有显式版本的情况下工作。
为了确保我们在同一页上,这就是我最初编写该内容的方式:
public File openOrCreate(String pathStr) throws FileNotFoundException,
IOException {
Path path = ReposioryProposition.getPath(pathStr);
File file = path.toFile();
if (!file.exists())
file.createNewFile();
return file;
}
但是我不确定会发生什么,FNFE是被扔掉还是被吞噬了? 我的意图是分别捕获它们,并为另一个做不同的事情。
您只需要在throws
列表中包括更一般的异常即可。 这已经指定该方法可以抛出此异常的任何子类。
特别是,无论如何,您都必须处理更通用的异常,并且该异常处理程序还将处理子类。 如果要显式处理子类,则必须在更一般的异常之前捕获它:
try {
...
}
catch (FileNotFoundException e) {
// handle subclass
}
catch (IOException e) {
// handle general exception (this will not be executed if the
// exception is actually a FileNotFoundException
}
如果您已经包含IOException,则最好从throws子句中忽略FileNotFoundException。
这样做完全不会影响行为。 FileNotFoundException仍将被抛出,您可以显式地捕获它(以及还具有另一个更一般的IOException捕获)。
在throws子句中具有IOException只是表明将从此方法引发IOException或其任何子类 。 FileNotFoundException包括在其中。
但是我需要明确地做吗? 它是否可以在没有显式版本的情况下工作,或更危险的是,有时会在没有显式版本的情况下工作。
是。 您必须明确地执行此操作,因为它是已检查的异常。
直接抛出异常:如果仅将那些检查过的异常添加到方法签名中,则意味着如果在方法标题中添加throws子句,例如throws IOException
,则无需捕获方法中的任何地方。
但这有一个缺陷,如果您正在代码中逐行访问n个文件,并且如果引发异常,则每一行都可能引发IOException。 您必须先关闭文件 .close()
然后再将其返回给调用的方法。 因此,仅使用this throws子句不会让您这样做。
因此,只需捕获异常并在catch或finally块中执行必要的操作即可。
仅当您不需要采取任何措施并且您希望将异常弹出到被调用方法中并且被调用方法可以处理该异常时,才将throws签名添加到该方法中。
这是Java语言规范必须说的 :
如果V的运行时类型与(§5.2)try语句的任何catch子句的可捕获异常类的赋值兼容, 则选择第一个(最左侧)此类catch子句 。 将值V分配给所选catch子句的参数,并执行该catch子句的Block,然后可以选择:...
(强调和省略号)。
因此,如果要执行更具体的catch
子句,则必须将其放在catch列表中的第一位。
您可以先捕获子类异常(如果没有),然后捕获通用异常类,例如
try{
// something
} catch(FileNotFoundException fne){
// Handle the exception here
} catch(IOException ioe) {
// Handle the IOException here
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.