Exceptions

Dr Andy Evans

[Fullscreen]

Problems

  • Encapsulation demands that we don't need to know what goes on in other's classes.
  • Fine and dandy, but what if our code causes their code to break horribly?
    	
    FileReader f = new FileReader(nonexistentFile);
    
    
  • To understand the framework for dealing with this, we need to understand Exceptions.

Exceptions

  • When something goes wrong we don't want the program to crash.
  • We want some way of doing something about it.
  • When the JVM detects an problem, it generates an Exception object at that point in the running code which represents that problem.
  • We can catch these and do something with them.
  • For example, if you try and add something to an array outside its size the JVM makes an object of type ArrayIndexOutOfBoundsException.

Exceptions

  • Different problems generate different exceptions.
  • If we build classes other people will use, we can define our own exceptions that are generated when the classes are misused.
  • We call this 'throwing' an exception.
  • If code potentially throws an exception, we must deal with the potentially thrown exception.

Catching exceptions

	
try {
	
    // Operations that throw an exception.

} catch (ExceptionType anyName) {

    //Operations that deal with 
	// the anyName exception.

}

  • The catch statement is the 'Exception Handler'.
  • The code stops acting at the problem point and jumps to the handler.

Example


try {

    FileWriter f = new FileWriter(someFile);
	
} catch (Exception e) {

    return "File not found";
	
}

f.write("Hello World"); // Breaks

Though this looks fine, there's a scope problem.

Example


FileWriter f = null;

try {

    f = new FileWriter(someFile);
	
} catch (Exception e) {

    return "File not found";
	
}

f.write("Hello World");

Note the separation of the variable label creation from the object creation to avoid scoping issues.

Problem objects

  • Exceptions are subclasses of a broader class Throwable.
  • Two main subclass branches...
    • Errors
    • Exceptions
  • Error objects are used in catastrophic system problems.
  • Exceptions are more frequent.
  • One of the most common subclasses of Exception is the RuntimeException.

Propagating

  • RuntimeExceptions can be left uncaught.
  • In this case they 'propagate' through the code.
  • The code stops at the problem point and jumps to where the method was called, and the exception object gets passed to that point.
  • This continues until the main method is reached if it's not handled.
  • The default handler then handles the problem.
  • Usually the program breaks and a 'stack trace' is printed. This lists all the methods the problem has propagated through.
	
public class MathsExample {
    public static void main (String args[]) {
	
		RubbishMaths r = new RubbishMaths();
		
    }
}

	
public class RubbishMaths {
    public RubbishMaths() {
	
		int answer = 12/0;
		
    }
}


[Fullscreen]

Nesting catches

  • What this propagation means is we can nest catches...

try {
    try {
		// Operation
    } catch (RuntimeException rte) {
		// Do something with rte.
    }

} catch (Exception e) {
    // Do something with e if 
	//  it's not a RuntimeException.
}

Laddered catches

	
try {
    // Operation
} catch (OurException oe) {
    // Do something with oe
} catch (Exception e) {
    // Do something with e if 
	//  it's not of type OurException.
}	

Sorting out

  • All exceptions except RuntimeExceptions, must be caught.
  • The usual thing in debugging is to print the error and the stack trace.
    	
    e.printStackTrace();
    
    
  • Can also write its name to a standard error log...
    	
    System.err.println(e);
    
    
    ...but this is usually the screen anyhow.
  • In a real program we should do something about the error so the user doesn't get a message.

Finally

  • If there's something you want to happen, even if there is an error, you should put it in a 'finally' block under your 'try'.
  • Finally blocks are always executed, even if written after returns.

try {
    // Operation.
} catch (Exception e) {
    // Do something with e.
} finally {
    // Do something important.
}


Making Exceptions

  • By saying that a method or an object must catch an exception, we can force programmers using our objects to prepare for problems.
  • We can use the keyword throws to do this.
  • If someone uses our object they must catch the thrown object or throw it again.
  • Eventually something must deal with it, or the program won't compile.

Creating

  • Subclass the class 'Exception' to make a new exception class, eg.
    	
    public class OurException extends Exception {
    
    
  • In our main class, declare that a method will be throwing an object if everything goes wrong...
    	
    public void name () throws OurException {
    
    
  • At some point in the code, throw the exception...
    	
    throw new OurException();
    
    

Summary

  • Exceptions and Errors give us a chance to manage problems without the user knowing.
  • The also allows us to force people who use our classes to deal with problems we know may arise.
  • Exceptions can be caught and handled, or thrown out of the method for someone else to deal with.
  • Exceptions propagate back through all the method calls and objects inside one another until they reach a suitable handler.

Review

	
try {
    // whatever
} catch (ExceptionType label) {
    // fix stuff
}