In Java, what is the difference between catching a general exception and a specific exception (e.g. IOException?)

Currently I am breaking only general exceptions, but I want to change this to catch certain exceptions, but what is the advantage of this?

+7
source share
7 answers

The difference between executing a general try / catch statement and catching a specific exception (e.g. FileNotFoundException) usually depends on which errors you should handle and which errors you don't need to worry about. For example:

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

The above code will catch EVERY exception that is thrown inside the try statement. But perhaps you do not want to handle every error. What can you do with the "OutOfMemory" exception?

The best way to handle errors is to perform some default actions if the error is unknown or something you canโ€™t do anything about, and take another action if you find that you can do โ€œPlan Bโ€ if you catch.

For example, suppose you are trying to open a file, but the file does not exist. You can catch a FileNotFoundException and create a new empty file, as shown below:

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

It was the most efficient and user-friendly error checking method I have used in the past.

+13
source

Capturing specific exceptions allows you to tailor specific answers for each case.

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

A few drawbacks of catching each exception separately include the entire try-catch structure, which becomes very large and makes the logic of the containing method more complex, and the need to repeat the code in many or all of the individual catch blocks (for example, registering an exception).

In some cases, the complexity of some basic API ensures that all different exceptions are processed and the try-catch structure is retrieved into the utility method. For example, invoking a method through reflection appears to regularly require facade APIs.

At the API design level, there is always a balance between

  • Very rich (public) exception hierarchy
  • Including error codes as part of the information contained in the base exception, and
  • Open set of marker interfaces and use of private subtypes of exceptions
+3
source

A good example that shows the ability to handle problems depending on the type of problem 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. } 

and corresponding:

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

In the last example, no means are provided for handling an exception based on what happened. All problems are handled the same way.

+2
source

If you have a block of code that can throw various exceptions, and you surround it with a common try {} catch {Exception e}, you wonโ€™t know what exactly happened and how you should handle this error.

+1
source

If you plan to use multiple users using your application, certain exceptions will let you know exactly where your program was unsuccessful if you control someone else. but besides this, if the program is intended only for you, you can simply run it through the debugger, although the habit of doing very descriptive and unambiguous error handling is good if you are ever planning to take programming to the masses :)

+1
source

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 is, it works ... usually. However, with an unspecified error, I can do nothing but warn the user. If I caught a FileNotFoundException in particular, I could try another file. If I caught an IOException purpose, I could warn of something else. This example is a bit weak, but it may give you some idea.

+1
source

The problem with catching common exceptions is that you end up catching (and often mistakenly) an 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 under the assumption that the only way that the code inside try can fail is if the file is missing or cannot be opened for any reason. In fact, if a method is called with a null file, or if there is an error in the code reading the file, then NPE and other unchecked exceptions are possible. This way, the code will hide errors by catching an Exception .

The correct version of the above code breaks an IOException (or maybe FileNotFoundException ) and allows you to throw unexpected exceptions.

+1
source

All Articles