在Java中,捕获genericsexception和特定exception(例如IOException?)之间的区别是什么?
目前我只捕获通用exception,但我希望更改此function以捕获特定exception,但这有什么优势?
执行常规try / catch语句和捕获特定exception(例如FileNotFoundException)之间的区别通常取决于您需要处理哪些错误以及您不必担心哪些错误。 例如:
catch (Exception e) { //A (too) general exception handler ... }
上面的代码将捕获在try语句中抛出的每个exception。 但也许你不想处理每一个错误。 你可以用“OutOfMemory”例外做什么?
更好的error handling方法是在错误未知或无法执行任何操作时执行某些默认操作,如果发现如果发现可以执行“计划B”,则执行其他操作。
例如,假设您正在尝试打开文件,但该文件不存在。 您可以捕获FileNotFoundException并创建一个新的空白文件,如下所示:
catch (FileNotFoundException e) { //A specific exception handler //create a new file and proceed, instead of throwing the error to the user }catch (Exception e) { //For all other errors, alert the user ... }
这是我过去使用的最有效和用户友好的错误检查方法。
捕获特定exception允许您针对每个案例定制特定响应。
在逻辑层面,一系列catch块与具有一个catch块相同,然后在单个catch块中编写自己的条件逻辑。 请注意,如果要访问子类型中声明的详细信息,则条件逻辑还必须将exception转换为特定子类型。
分别捕获每个exception的几个缺点包括整个try-catch结构变得非常大并且使得包含方法的逻辑更难遵循,并且必须在许多或所有单独的catch块中重复代码(例如,记录exception) )。
在某些情况下,某些底层API的复杂性保证了对所有不同exception的处理以及将try-catch结构提取到实用方法中。 例如,通过reflection的方法调用似乎定期保证具有外观API。
在API设计层面,总是存在平衡行为
- 一个非常丰富的(公共)exception层次结构
- 将错误代码合并为某些基本exception中包含的信息的一部分,以及
- 一组公共标记接口并使用私有exception子类型
一个很好的示例,显示了根据发生的问题类型处理问题的能力:
try { // open a file based on its file name } catch (FileNotFoundException e) { // indicate that the user specified a file that doesn't exist. // reopen file selection dialog box. } catch (IOException e) { // indicate that the file cannot be opened. }
而相应的:
try { // open a file based on its file name. } catch (Exception e) { // indicate that something was wrong // display the exception's "reason" string. }
后一个示例没有根据发生的问题提供处理exception的方法。 所有问题都以同样的方式处理。
如果你有一个可以抛出不同exception的代码块,并且用一般的try {} catch {Exception e}来包围它,你就不会知道究竟发生了什么以及你应该如何处理错误。
如果您计划使用您的应用程序的多个人,具有特定的例外将让您知道您的程序在其他人的控制下失败的确切位置。 但除此之外,如果该程序仅适用于您自己,您可以通过调试器运行它,尽管习惯性地进行非常具有描述性和明确性的error handling是很好的,如果您曾经计划过编程给大众:)
举个例子:
try { StringBuffer fileData = new StringBuffer(1000); BufferedReader reader = new BufferedReader( new FileReader(filePath)); char[] buf = new char[1024]; int numRead=0; while((numRead=reader.read(buf)) != -1){ fileData.append(buf, 0, numRead); } reader.close(); return fileData.toString(); } catch (Exception e) { //do something generic - maybe log it }
就目前而言,它通常起作用。 然而,由于模糊的错误捕获,除了警告用户之外,我无法做任何事情。 如果我特意捕获了FileNotFoundException
,我可以尝试另一个文件。 如果我特意捕获了IOException
,我可能会警告其他事情。 这个例子有点弱,但它可能会给你一些想法。
捕获genericsexception的问题是您最终捕获(并且经常处理不当)意外exception。 例如:
public String readFile(File file) { try { Reader r = new FileReader(file); // read file return ...; // the file contents } catch (Exception ex) { // file not found ... return ""; } }
正如您所看到的,上面的内容是假设try
中的代码失败的唯一方法是文件丢失,或者由于某种原因无法打开。 实际上,如果使用null
文件调用该方法,或者如果代码中存在读取该文件的某些错误,则NPE和其他未经检查的exception是可能的。 因此,代码将通过捕获Exception
来隐藏错误。
上面代码的正确版本将捕获IOException
(或者可能是FileNotFoundException
)并让意外的exception传播。