3

Like i have these two scenarios where we have to handle FileNotFoundException

Case1:

    try {
        FileInputStream fis = new FileInputStream("test1.txt");
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } 

Case2:

    try {
        FileInputStream fis = new FileInputStream("test1.txt");
    } catch (Exception e) {
        e.printStackTrace();
    }

In both cases printed Stack Trace is same. I would like to know the difference between both implementations and what should be preferred ?

Stewartside
  • 20,378
  • 12
  • 60
  • 81
quintin
  • 812
  • 1
  • 10
  • 35
  • Wow! Four answers and not one of them mentions inheritance, or explains *why* or *how* the two cases give the same result. – Biffen Apr 30 '15 at 10:44

7 Answers7

5

From the docs it gives the reason:

"A subclass inherits all the members (fields, methods, and nested classes) from its superclass. Constructors are not members, so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass."

Exception class is the parent of all the other exception class. So if you know that you are going to get the FileNotFoundException then it is good to use that exception. Making the Exception is a generic call.

This would help you understand:

enter image description here

So as you can see that the Exception class is at a higher hierarchy, so it means it would catch any exception other than the FileIOExcetion. But if you want to make sure that an attempt to open the file denoted by a specified pathname has failed then you have to use the FileIOExcetion.

So here is what an ideal approach should be:

try {
      // Lets say you want to open a file from its file name.
    } catch (FileNotFoundException e) {
      // here you can indicate that the user specified a file which doesn't exist.
      // May be you can try to reopen file selection dialog box.
    } catch (IOException e) {
      // Here you can indicate that the file cannot be opened.
    }

while the corresponding:

try {
  // Lets say you want to open a file from its file name.
} catch (Exception e) {
  // indicate that something was wrong
  // display the exception's "reason" string.
}

Also do check this: Is it really that bad to catch a general exception?

Community
  • 1
  • 1
Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
  • While I am not the downvoter I do agree with it, kinda; for the reason I mentioned in my answer: catching `Exception` also means that you catch all unchecked exceptions, which is not a good thing to do imho. – fge Apr 30 '15 at 10:45
1

In case 2, the catch block will be run for all Exceptions that are caught, irrespective of what exception they are. This allows for handling all exceptions in the same way, such as displaying the same message for all types of exceptions.

In case 1, the catch block will be run for FileNotFoundExceptions only. Catching specific exceptions in different catch blocks allows for the handling of different exceptions in different ways, such as displaying a different message to the user.

1

When an exception occures the JVM throws the instance of the Exception and that instance is passed to the respective catch block , so in catch(Exception e) e is just the reference variable , but the instance it points to is of Exception thrown .

In case of catch(FileNotFoundException e) , e is also a reference variable and the instance it points to is of Exception thrown , so in both cases different reference varibales (i.e. e) are pointing to the instance of same the Exception (which is thrown) .

this is what i prefer :

    try {
        // some task
    } catch (Exception e) {
        if (e instanceof FileNotFoundException) {

            // do this
        }
        if (e instanceof NullPointerException) {
            // do this
        } else {
            // do this
        }
    }
Alok Mishra
  • 926
  • 13
  • 39
0

It is a matter of what you want to intercept. With Exception you will catch any exception but with FileNotFoundException you will catch only that error case, allowing the caller to catch and apply any processing.

0

Don't use any of those.

Don't catch Exception. Why? Because it also catches all unchecked exceptions (ie, RuntimeExceptions and derivates). Those should be rethrown.

Don't use the old file API. Why? Because its exceptions are unreliable (FileNotFoundException can be thrown if you try and open a file to which you have no read access to for instance).

Use that:

final Path path = Paths.get("test1.txt");
try (
    final InputStream in = Files.newInputStream(path);
) {
    // do something with "in"
} catch (FileSystemException e) {
    // fs level error: no permissions, is a directory etc
} catch (IOException e) {
    // I/O error
}

You do need to catch FileSystemException before IOException since the former is a subclass of the latter. Among other possible exceptions you can have: AccessDeniedException, FileSystemLoopException, NoSuchFileException etc.

fge
  • 119,121
  • 33
  • 254
  • 329
0

Exception class is the parent of FileNotFoundException.

If you have have provided the Exception in the catch statement, every Exception will be handled in the catch block. But if FileNotFoundException is present in catch block, only exceptions rising due to absence of a File at said source or permissions not available to read the file or any such issues which makes spoils Java's effort to read the file will be handled. All other exceptions will escape and move up the stack.

In the code snippet provided by you, it is fine to use both. But i would recommend FileNotFoundException as it points to exact issue in the code.

For more detail you can read Go Here

Ravi Ranjan
  • 740
  • 2
  • 10
  • 31
  • "only exceptions rising due to absence of a File at said source will be handled" <-- well, no. `FileNotFoundException` is also thrown if you don't have read access, or you are trying to open a directory, or... It is as useless an exception as java.nio.file's `FileSystemException` and derivates are useful. – fge Apr 30 '15 at 10:48
0

When you write this:

  try {
        FileInputStream fis = new FileInputStream("test1.txt");
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } 

The code inside the catch block is only executed if the exception (thrown inside the try block) is of type FileNotFoundException (or a subtype). When you write this, on the other hand:

try {
        FileInputStream fis = new FileInputStream("test1.txt");
    } catch (Exception e) {
        e.printStackTrace();
    }

the catch block is executed for any exception (since Exception is the root type of any exception).

If your file (test1.txt) does not exist, a FileNotFoundException is thrown and both code snippets are able to catch it. Try and change it to something like:

    try {
            FileInputStream fis = new FileInputStream("test1.txt");
        } catch (NullPointerException e) {
            e.printStackTrace();
        }

and you will see that the catch block is no longer executed.

Evil Toad
  • 3,053
  • 2
  • 19
  • 28