Previous
Index

Next

Objective 3, try/catch and overridden methods

Write code that makes proper use of exceptions and exception handling clauses (try catch finally) and declares methods and overriding methods that throw exceptions.

An exception condition is a when a program gets into a state that is not quite normal. Exceptions trapping is sometimes referred to as error trapping. A typical example of an exception is when a program attempts to open a file that does not exist or you try to refer to an element of an array that does not exist.

The try and catch statements are part of the exception handling built into Java. Neither C/C++ nor Visual Basic have direct equivalents to Java's built in exceptions. C++ does support exceptions but they are optional, and Visual Basic supports On Error/Goto error trapping, which smacks somewhat of a throwback to an earlier less flexible era of BASIC programming.

Java exceptions are a built in part of the language. For example if you are performing I/O you must put in exception handling. You can of course put in null handling that doesn't do anything. The following is a little piece of code I have used with Borland/Inprise JBuilder to temporarily halt output to the console and wait for any key to be pressed.

public class Try{ 
import java.io.*; 
    public static void main(String argv[]){
        Try t = new Try(); 
        t.go(); 
    }//End of main
public void go(){ 
     try{ 
    InputStreamReader isr = new InputStreamReader(System.in);
    BufferedReader br = new BufferedReader(isr);
        br.readLine(); 
      } catch(Exception e){
     /*Not doing anything when exception occurs*/
     } //End of try
    System.out.println("Continuing"); 
   }//End of go 
}

In this case nothing is done when an error occurs, but the programmer must still acknowledge that an error might occur. If you remove the try and catch clause the code will simply not compile. The compiler knows that the I/O methods can cause exceptions and demands exception handling code.

Comparing with Visual Basic and C/C++

This is a little more rigorous than Visual Basic or C/C++ which allows you to throw together "quick and dirty" programs that pretend they are in a world where errors do not occur. Remember that the original version of DOS was called QDOS for Quick and Dirty DOS by it's creator and look how long we have lived with the legacy of that bit of hackery. By the time you have gone to the trouble of putting in a try/catch block and blank braces you may as well put in some real error tracking. It's not exactly bondage and discipline programming, it just persuasively encourages you to "do the right thing".



Overriding methods that throw exceptions

An overriding method in a subclass may only throw exceptions declared in the parent class or children of the exceptions declared in the parent class. This is only true for overriding methods not overloading methods. Thus if a method has exactly the same name and arguments it can only throw exceptions declared in the parent class, or exceptions that are children of exceptions in the parent declaration. It can however throw fewer or no exceptions. Thus the following example will not compile

import java.io.*;
class Base{
public static void amethod()throws FileNotFoundException{}
}

public class ExcepDemo extends Base{
  //Will not compile, exception not in base version of method
  public static void amethod()throws IOException{}
}



If it were the method in the parent class that was throwing IOException and the method in the child class that was throwing FileNotFoundException this code would compile. Again, remember that this only applies to overridden methods, there are no similar rules to overloaded methods. Also an overridden method in a sub class may throw Exceptions.

The throws clause

One of the issues created with the need to include try/catch blocks in code that may throw an exception is that you code can start to appear to more about what might happen than about what should happen. You can pass exceptions "up the stack" by using the throws clause as part of the method declaration. This in effect says "when an error occurs this method throws this exception and it must be caught by any calling method".

Here is an example of using the throws clause

import java.io.*;
public class Throws{
    public static void main(String argv[]){
        Throws t = new Throws();
    try{
    t.amethod();
    }catch (IOException ioe){}
        }
    

    public void amethod() throws IOException{
        FileInputStream fis = new FileInputStream("Throws.java");
    }
}



Questions

Question 1)

What will happen when you attempt to compile and run the following code?

import java.io.*;
class Base{
public static void amethod()throws FileNotFoundException{}
}



public class ExcepDemo extends Base{
public static void main(String argv[]){
       ExcepDemo e = new ExcepDemo();
}

public static void amethod(){}
protected ExcepDemo(){
 try{
  DataInputStream din = new DataInputStream(System.in);
  System.out.println("Pausing");
  din.readChar();
  System.out.println("Continuing");
  this.amethod();
  }catch(IOException ioe) {}

}



}

1) Compile time error caused by protected constructor
2) Compile time error caused by amethod not declaring Exception
3) Runtime error caused by amethod not declaring Exception
4) Compile and run with output of "Pausing" and "Continuing" after a key is hit


Question 2)

What will happen when you attempt to compile and run the following code?

import java.io.*;
class Base{
public static void amethod()throws FileNotFoundException{}
}



public class ExcepDemo extends Base{
public static void main(String argv[]){
       ExcepDemo e = new ExcepDemo();
}

public static void amethod(int i)throws IOException{}



private ExcepDemo(){
 try{
    DataInputStream din = new DataInputStream(System.in);
    System.out.println("Pausing");
    din.readChar();
    System.out.println("Continuing");
    this.amethod();
    }catch(IOException ioe) {}
  }



}

1) Compile error caused by private constructor
2) Compile error caused by amethod declaring Exception not in base version
3) Runtime error caused by amethod declaring Exception not in base version
4) Compile and run with output of "Pausing" and "Continuing" after a key is hit


Question 3)

What will happen when you attempt to compile and run this code?

import java.io.*;
class Base{
public static void amethod()throws FileNotFoundException{}
}



public class ExcepDemo extends Base{
public static void main(String argv[]){
       ExcepDemo e = new ExcepDemo();
}

public static void amethod(int i)throws IOException{}
private boolean ExcepDemo(){
 try{
    DataInputStream din = new DataInputStream(System.in);
    System.out.println("Pausing");
    din.readChar();
    System.out.println("Continuing");
    this.amethod();
    return true;
    }catch(IOException ioe) {}
    finally{
    System.out.println("finally");
    }
    return false;
  }

}

1) Compilation and run with no output.
2) Compilation and run with output of "Pausing", "Continuing" and "finally"
3) Runtime error caused by amethod declaring Exception not in base version
4) Compile and run with output of "Pausing" and "Continuing" after a key is hit


Question 4)

Which of the following require explicit try/catch exception handling by the programmer

1)Traversing each member of an array
2) Attempting to open a file
3) Attempting to open a network socket
4) Accessing a method in other class

Question 5)

What will happen when you attempt to compile the following code?

import java.io.*;
class granary{
    public void canal() throws IOException{
    System.out.println("canal");
    }
}

public class mmill extends granary{
    public static void main(String argv[]){
    System.out.println("mmill");
    }
    public void canal(int i) throws Exception{
    System.out.println("mmill.canal");
    }
    public void  canal(long i) {
    System.out.print("i");
    }
}

1) Compile time error
2) Runtime errors
3) Compile error, mmill version of canal throws Exception not in granary version
4) Compilation and run with output of mmill



Answers

Answer to Question 1)

4) Compile and run with output of "Pausing" and "Continuing" after a key is hit

An overridden method in a sub class must not throw Exceptions not thrown in the base class. In the case of the method amethod it throws no exceptions and will thus compile without complaint. There is no reason that a constructor cannot be protected.

Answer to Question 2)

4) Compile and run with output of "Pausing" and "Continuing" after a key is hit
In this version amethod has been overloaded so there are no restrictions on what Exceptions may or may not be thrown.


Answer to Question 3)

1) Compilation and run with no output.

OK, I have wandered off topic here a little. Note that the constructor now has a return value. This turns it into an ordinary method and thus it does not get called when an instance of the class is created.


Answer to Question 4)

2) Attempting to open a file
3) Atempting to open a network socket

Generally speaking, all I/O operations require explicit exception handling with try/catch blocks. The JDK 1.4 exams does not explicitly cover I/O but it may be referred to in the context of exception handling.

Answer to Question 5)

4) Compilation and run with output of mmill

The limitations on what exceptions can be thrown only applies to methods that are overriden, not to methods that are overloaded. Because the method canal is overloaded (ie it takes a different parameter type) in the mmill version there is no compile or runtime problem.


Other sources on this topic

This topic is covered in the Sun Tutorial at
http://java.sun.com/docs/books/tutorial/essential/exceptions/definition.html

Jyothi Krishnan on this topic at
http://www.geocities.com/SiliconValley/Network/3693/obj_sec2.html#obj7

Bruce Eckel Thinking in Java
http://codeguru.earthweb.com/java/tij/tij0096.shtml


Central Connecticut State University
http://chortle.ccsu.ctstateu.edu/cs151/Notes/chap80/ch80_1.html






Previous
Index

Next