Handling exceptions in Java

Java has two ways of handling checked exceptions. This is very handy, and you need to know how to do both of them.

In your programs, you are expected to use TRY-CATCH instead of just "THROWS IOEXCEPTION", and also to use the TRY-WITH_RESOURCES syntax.

I. Throwing the exception up the stack

This is used to pass the exception to a higher up method which may be able to figure out what to do better.

Example - specifically for showing how to pass an exception to the calling method.
* main calls getFile
* getFile calls parseFN


static void main(String[] args) {

   boolean fileOpened = false;
   while (!fileOpened) {
      try {
         File f = getfile();
         fileOpened = true;
      } catch (ParseExcption e) {
         System.out.println("You typed in a bad filename, try again");
         //it will loop back ...
      } catch (IOException e) {
         System.out.println ("An IO exception occurred. Kill program!".)
         e.printStackTrace();
         System.exit(0);
      }
   }	
}

static File getFile() throws ParseException, IOException{
   String fname = getFname();
   fname = parseFN(fname);
   return new File(fname);
}


static String parseFN(String fname) throws ParseException{
   // ....
   // if the file name is invalid, we'll throw an exception
   throw new ParseException("filename has invalid charachers",1);
   return fname;
}

 

In this example, we feel that the main program is the place where we want to decide what to do if there is an error.
For filename errors, we'll try again. For Other IO errors, just kill the program and print a stacktrace

 

 

 

This method, gets a filename, checks to see if it's valid by calling parseFN(), and then opens a file creates a file object. This latter action can cause an IOException. We'll let the parent method handle both of these things.

 

This method, parseFN, checks to see if the filename is valid. If it is not, we don't know what exactly to do, so we'll throw an exception. I'm using ParseException since it already exists and can be used for something like this.
(The constructor takes an INT offset, so I just put in 1)

II. Using try-catch

This structure is used to handle an exception. The exception can be one created in this method, or from a method lower down in the stack.

basic example

• TRY{} is used to surround the code that may cause an error.
• CATCH{} is used to surround the code that should be executed if there is an error
• CATCH must specify the exception that it wants to catch.
DO NOT WRITE catch (Exception e) {}. It is very bad style to just catch every exception.

try{  
   z = x / y;
}  
catch(ArithmeticException e){
   System.out.println("division by zero");
   z = 0;
}  
//program continues (instead of crashing)

Arithmetic Exceptions are unchecked exceptions so you do not have to put them in a try-catch block.
The fact that they do not need to be caught is a good indication that it is normally a bad idea to do this.
Do not write code to catch ArithmeticException or ArrayIndexOutOfBoundException or NullPointerException etc.

Here is the better way of coding it (without using exceptions).

if (y != 0) z = x / y;
else        z = 0;

Other things with try-catch

Finally

The optional finally {} block is always executed regardless of whether there is an error or not.
It is often used to close files, however, this is better done with "try with resources" (see below)

• The finally block will NOT be executed if program exits by calling System.exit().
• For each try block there can be zero or more catch blocks, but only one finally block.

Multiple catch block

You can catch multiple exceptions, however, only one exception at a time will be thrown and caught.
All catch blocks must be ordered from most specific to most general i.e. catch for ArithmeticException must come before catch for Exception.

try{  
   ...
}  
catch(ArithmeticException e){...}  
catch(ArrayIndexOutOfBoundsException e){...}  
catch(Exception e) {...}   ← Do not actually do this

 In reality, don't catch any of these. The first two are unchecked exceptions.

Multiple catch blocks - part 2

You can also catch more than one exception at once if you want to. This uses the same catch{ } block for both.

try {
  ...
}
catch (MalformedURLException | IOException ex) {
	System.out.println(ex.toString());
}

Try with resources

From https://www.baeldung.com/java-try-with-resources

Support for try-with-resources — introduced in Java 7 — allows us to declare resources to be used in a try block with the assurance that the resources will be closed after the execution of that block. (The resources declared need to implement the AutoCloseable interface.) Simply put, to be auto-closed, a resource has to be both declared and initialized inside the try:

try (InputStream inFile = new FileInputStream("test")) {
	inFile.read();
	...
        //call a method here to do whatever you want with the data
} catch(SomeException e) {
	...
}
finally {  //You probably won't need this.
	//No need to add code to close InputStream. Its close method will be internally called.
	//but if you do need something else, then you can put it here.
}

In its simplest form:

try (PrintWriter writer = new PrintWriter(new File("test.txt"))) {
    writer.println("Hello World");
}
We can declare multiple resources just fine in a try-with-resources block by separating them with a semicolon:
try (Scanner scanner = new Scanner(new File("testRead.txt")) ;
    PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) {
    while (scanner.hasNext()) {
	writer.print(scanner.nextLine());
    }
}
A try-with-resources block can still have the catch and finally blocks, which will work in the same way as with a traditional try block. You'll still need a catch block to do something with exceptions that are thrown.
Problem: Since the try with resources automatically closes the resource as well, this can lead to problems as the close() operation can also throw an exception. In some situations, only one exception is thrown, the other is suppressed. Look up "suppressed exceptions" if you are using try-with-resources and you need to make sure that you detect the exception thrown by a close() operation.

The Exception object   useful methods

 

Please continue on reading about File I/O now

References

For more information about try-catch, read JavaTPoint. This excellent site also explains "try with resources" very well.

Other sites:
javapapers
mykong
journaldev