在 Java 中,捕获通用异常和特定异常(例如 IOException?)有什么区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5979501/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 13:49:07  来源:igfitidea点击:

In Java, what is the difference between catch a generic exception and a specific exception (eg. IOException?)

javaexception

提问by Renato Dinhani

Currently I'm catching only generic exceptions, but i want change this to catch the specific exceptions, but what is the advantage of this?

目前我只捕获通用异常,但我想改变它以捕获特定异常,但这样做有什么好处?

回答by Kyle

The difference between performing a general try/catch statement and catching a specific exception (e.g. a FileNotFoundException) typically depend on what errors you need to handle and what errors you don't need to worry about. For instance:

执行一般的 try/catch 语句和捕获特定异常(例如 FileNotFoundException)之间的区别通常取决于您需要处理哪些错误以及您不需要担心哪些错误。例如:

catch (Exception e) {    //A (too) general exception handler
...
}

The code above will catch EVERY exception that is thrown inside of the try statement. But maybe you don't want to handle every error. What can you do with an "OutOfMemory" exception?

上面的代码将捕获在 try 语句中抛出的每个异常。但也许您不想处理每个错误。你能用“OutOfMemory”异常做什么?

A better method of error handling would be to perform some default action if the error is unknown or something you can't do anything about, and perform another action if you discover that you can do "Plan B" if you catch.

一种更好的错误处理方法是,如果错误未知或您无能为力,则执行一些默认操作,如果发现可以执行“B 计划”,则执行另一个操作。

For example, assume you are trying to open a file, but the file doesn't exist. You can catch the FileNotFoundException and create a new blank file as below:

例如,假设您尝试打开一个文件,但该文件不存在。您可以捕获 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
    ...
}

This has been the most effective and user-friendly method of error checking that I've used in the past.

这是我过去使用过的最有效和用户友好的错误检查方法。

回答by Dilum Ranatunga

Catching specific exceptions allows you to tailor specific responses to each case.

捕获特定的异常允许您针对每个案例定制特定的响应。

At a logical level, a series of catch blocks is the same as having one catch block, and then writing your own conditional logic inside the single catch block. Note that the conditional logic would also have to cast the exception as specific subtypes if you want access to detailed information declared within the subtype.

在逻辑层面上,一系列 catch 块等同于拥有一个 catch 块,然后在单个 catch 块中编写您自己的条件逻辑。请注意,如果您想访问子类型中声明的详细信息,条件逻辑还必须将异常转换为特定子类型。

The few disadvantages of catching each exception separately include the whole try - catch structure growing very large and making the logic of the containing method harder follow, and having to repeat code in many or all of the separate catch blocks (for example, logging the exception).

单独捕获每个异常的几个缺点包括整个 try-catch 结构变得非常大并且使包含方法的逻辑更难遵循,并且必须在许多或所有单独的 catch 块中重复代码(例如,记录异常)。

In certain cases, the complexity of some underlying API warrants both the handling of all the different exceptions andthe extraction of the try-catch structure into a utility method. For example, method invocation through reflection seems to regularly warrant having facade APIs.

在某些情况下,一些底层 API 的复杂性保证了处理所有不同的异常将 try-catch 结构提取到实用方法中。例如,通过反射的方法调用似乎经常保证拥有外观 API。

At an API design level, there is always a balancing act between

在 API 设计级别,总是有一个平衡的行为

  • A very rich (public) exception hierarchy
  • Incorporating error codes as part of the information contained in some base exception, and
  • A public set of marker interfaces and using private exception subtypes
  • 一个非常丰富的(公共)异常层次结构
  • 将错误代码作为包含在某些基本异常中的信息的一部分,以及
  • 一组公共标记接口和使用私有异常子类型

回答by Edwin Buck

A good example that shows the ability to handle issues based on the type of issue that occurred:

一个很好的例子,展示了根据发生的问题类型处理问题的能力:

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.
}

while the corresponding:

而相应的:

try {
  // open a file based on its file name.
} catch (Exception e) {
  // indicate that something was wrong
  // display the exception's "reason" string.
}

The latter example provides no means for handling the exception based on what issue occurred. All issues get handled the same way.

后一个示例没有提供根据发生的问题处理异常的方法。所有问题都以同样的方式处理。

回答by josh.trow

Take this example:

拿这个例子:

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
}

As it stands, it works...usually. However, with the vague error catching I can't really do anything except warn the user. If I caught the FileNotFoundExceptionspecifically, I could try another file. If I caught the IOExceptionspecifially, I could warn about something else. This example is a bit weak, but it may give you some idea.

就目前而言,它的工作原理......通常。但是,由于模糊的错误捕获,除了警告用户之外,我真的什么也做不了。如果我特别抓住了FileNotFoundException,我可以尝试另一个文件。如果我特别抓住了IOException,我可以警告其他事情。这个例子有点弱,但它可能会给你一些想法。

回答by Stephen C

The problem with catching generic exceptions is that you end up catching (and often mishandling) unexpected exception. For example:

捕获通用异常的问题在于您最终会捕获(并且经常错误处理)意外的异常。例如:

    public String readFile(File file) {
        try {
            Reader r = new FileReader(file);
            // read file
            return ...;  // the file contents
        } catch (Exception ex) {
            // file not found ...
            return "";
        }
    }

As you can see, the above is written on the assumption that the only way that the code inside the trycan fail is if the file is missing, or can't be opened for some reason. In fact, if the method is called with a nullfile, or if there is some bug in the code that reads the file, NPEs and other unchecked exceptions are possible. Thus the code is going to hide bugs by catching Exception.

如您所见,上述内容是基于以下假设编写的:其中的代码try可能失败的唯一方法是文件丢失或由于某种原因无法打开。事实上,如果该方法是用null文件调用的,或者如果读取文件的代码中存在一些错误,则可能会出现 NPE 和其他未经检查的异常。因此,代码将通过捕获来隐藏错误Exception

The correct version of the code above would catch IOException(or maybe FileNotFoundException) and let the unexpected exceptions propagate.

上面代码的正确版本将捕获IOException(或可能FileNotFoundException)并让意外的异常传播。

回答by abalogh

If you have a block of code which can throw different exceptions, and you surround that with a general try {} catch {Exception e}, you won't know what exactly happened and how you should handle the error.

如果你有一个可以抛出不同异常的代码块,并且你用一个通用的 try {} catch {Exception e} 来包围它,你将不知道到底发生了什么以及你应该如何处理错误。

回答by Richard Smith

If you plan on multiple people using your application, having specific exceptions will let you know exactly where your program failed when under the control of someone else. but aside from that, if the program is only for yourself, you can just run it through a debugger, although being in the habit of making very descriptive and unambiguous error handling is a great on to have, if you ever do plan on taking your programming to the masses :)

如果您计划让多人使用您的应用程序,则具有特定的异常可以让您确切地知道程序在其他人的控制下失败的地方。但除此之外,如果该程序仅供您自己使用,您可以通过调试器运行它,尽管如果您打算将自己的程序带入面向大众编程 :)