Previous |
Next |
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.
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".
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.
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"); } }
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
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
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
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
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
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.
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.
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.
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.
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.
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 |
Next |