MSc IT Programming Methodology (2)
THROWS an EXCEPTION Errors?
By the end of this lecture you should be able to: explain the term exception distinguish between checked and unchecked exception classes in Java claim an exception using a throws clause throw an exception using a throw command catch an exception in a try catch block; define and use your own exception classes. Exceptions
Pre-defined exception classes in Java
Throwable
Exception Error
Throwable Exception Error RuntimeException IOException
Throwable FileNotFoundException Exception Error RuntimeException IOException
Throwable FileNotFoundException Exception Error RuntimeException IOException IllegalArgumentException IndexOutOfBoundsException
Throwable NumberFormatException FileNotFoundException Exception Error RuntimeException IOException IllegalArgumentException IndexOutOfBoundsException
Throwable NumberFormatException ArrayIndexOutOfBoundsException FileNotFoundException Exception Error RuntimeException IOException IllegalArgumentException IndexOutOfBoundsException
Throwable NumberFormatException ArrayIndexOutOfBoundsException FileNotFoundException Exception Error RuntimeException IOException IllegalArgumentException IndexOutOfBoundsException Unchecked
Throwable NumberFormatException ArrayIndexOutOfBoundsException FileNotFoundException Exception Error RuntimeException IOException IllegalArgumentException IndexOutOfBoundsException Unchecked
Throwable NumberFormatException ArrayIndexOutOfBoundsException FileNotFoundException Exception Error RuntimeException IOException IllegalArgumentException IndexOutOfBoundsException Checked
Java Compiler RuntimeException NumberFormatException IOException FileNotFoundException WARNING!
Handling exceptions: an example
public class AptitudeTest { public static void main (String[] args) { int score; System.out.print("Enter aptitude test score: "); score = TestException.getInteger( ); // test score here } } Let’s look at the code for this method.
Outline TestException class public class TestException { public static int getInteger() { // code for method goes here } }
The read method of System.in
"hello" System.in.read( [ ] ) array of bytes 104,101,108, 111,13,10
Coding the getInteger method
This is a first attempt, it will not compile! byte [] buffer = new byte[512]; System.in.read(buffer); String s = new String (buffer); s = s.trim(); int num = Integer.parseInt(s); return num; System.in.read(buffer); TThe read method may throw a checked IOException
Dealing with exceptions..
main getInteger read
main getInteger read IOException!
main getInteger read catch
main getInteger read IOException!
main getIntegerread throw
main getInteger IOException! read throw
main getInteger IOException! read
main getIntegerread catch
main getInteger IOException! read
maingetIntegerread throw
main IOException! getIntegerread throw
Claiming an exception
To claim an exception we add a throws clause to our method header import java.io.* public class TestException { private static int getInteger( ) throws IOException { // as before } } This method will pass on the IOException error.
Revisiting the AptitudeTest class public class AptitudeTest { public static void main (String[] args) { int score; System.out.print("Enter aptitude test score: "); score = TestException.getInteger( ); // test score here } } score = TestException.getInteger( );
main IOException! getIntegerread throw
main IOException! getIntegerread
main getIntegerread catch
main IOException! getIntegerread
maingetIntegerread throw PROGRAM CRASH!!!!
import java.io.*; public class AptitudeTest { public static void main (String[] args) throws IOException { int score; System.out.print("Enter aptitude test score: "); score = TestException.getInteger( ); if (score >= 50) { System.out.println("You have a place on the course!"); } else { System.out.println("Sorry, you failed your test"); } } }
A test run Enter aptitude test score: java.lang.NumberFormatException: 12w at java.lang.Integer.parseInt(Integer.java:418) at java.lang.Integer.parseInt(Integer.java:458) at TestException.getInteger(TestException.java:10) at AptitudeTest.main(AptitudeTest.java:11) 12w
Enter aptitude test score: java.lang.NumberFormatException: 12w at java.lang.Integer.parseInt(Integer.java:418) at java.lang.Integer.parseInt(Integer.java:458) at TestException.getInteger(TestException.java:10) at AptitudeTest.main(AptitudeTest.java:11) 12w A Stack Trace
NumberFormatException byte [] buffer = new byte[512]; System.in.read(buffer); String s = new String (buffer); s = s.trim(); int num = Integer.parseInt(s); return num; int num = Integer.parseInt(s);
Catching an exception. In order to trap the exception object in a catch block you must surround the code that could generate the exception in a try block.
Syntax for using a try and catch block try { // code that could generate an exception } catch (Exception e) { // action to be taken when an exception occurs } // other instructions could be placed here
Some methods of the Exception class methoddescription printStackTrace prints (onto the console) a stack trace of the exception toString returns a detailed error message getMessage returns a summary error message
import java.io.*; public class AptitudeTest2 { public static void main (String[ ] args) { try { // as before score = TestException.getInteger( ); // as before } catch (NumberFormatException e) { System.out.println("You entered an invalid number!"); } catch (IOException e) { System.out.println(e); } System.out.println("Goodbye"); } }
Test Run of ApititudeTest2 Enter aptitude test score:12w You entered an invalid number! Goodbye
import java.io.*; public class AptitudeTest2 { public static void main (String[ ] args) { try { // as before score = TestException.getInteger( ); // as before } catch (NumberFormatException e) { System.out.println("You entered an invalid number!"); } catch (IOException e) { System.out.println(e); } System.out.println("Goodbye"); }
import java.io.*; public class AptitudeTest2 { public static void main (String[ ] args) { try { // as before score = TestException.getInteger( ); // as before } catch (NumberFormatException e) { System.out.println("You entered an invalid number!"); } catch (IOException e) { System.out.println(e); } System.out.println("Goodbye"); } Generates a NumberFormatException
import java.io.*; public class AptitudeTest2 { public static void main (String[ ] args) { try { // as before score = TestException.getInteger( ); // as before } catch (NumberFormatException e) { System.out.println("You entered an invalid number!"); } catch (IOException e) { System.out.println(e); } System.out.println("Goodbye"); }
import java.io.*; public class AptitudeTest2 { public static void main (String[ ] args) { try { // as before score = TestException.getInteger( ); // as before } catch (NumberFormatException e) { System.out.println("You entered an invalid number!"); } catch (IOException e) { System.out.println(e); } System.out.println("Goodbye"); }
import java.io.*; public class AptitudeTest2 { public static void main (String[ ] args) { try { // as before score = TestException.getInteger( ); // as before } catch (NumberFormatException e) { System.out.println("You entered an invalid number!"); } catch (IOException e) { System.out.println(e); } System.out.println("Goodbye"); }
Exceptions in GUI applications room should be a number
Using exceptions in your own classes
Look back at the Bank constructor: public Bank(int sizeIn) { list = new BankAccount[sizeIn]; total = 0; } A negative value would cause a NegativeArraySizeException.
Making use of exceptions: a first attempt
public Bank(int sizeIn) throws NegativeArraySizeException { list = new BankAccount[sizeIn]; total = 0; } Reveals that we are using an array.
Making use of exceptions: a second attempt
public Bank (int sizeIn) throws Exception { if (sizeIn < 0) { throw new Exception ("can’t set a negative size"); } else { list = new BankAccount[sizeIn]; total = 0; } }
Testing for the exception
public class BankProgram { public static void main(String[] args) { try { System.out.print(“Maximum number of accounts?“); size = EasyScanner.nextInt(); Bank myBank = new Bank(size); // rest of code here } catch (Exception e) { System.out.println(e.getMessage()); } } // other static methods here as before
Creating your own exception classes
Throwable NumberFormatException ArrayIndexOutOfBoundsException FileNotFoundException Exception Error RuntimeException IOException IllegalArgumentException IndexOutOfBoundsException
Throwable NumberFormatException ArrayIndexOutOfBoundsException FileNotFoundException Exception Error RuntimeException IOException IllegalArgumentException IndexOutOfBoundsException NegativeSizeException
public class NegativeSizeException extends Exception { public NegativeSizeException () { super("cannot set a negative size"); } public NegativeSizeException (String message) { super (message); } }
Amending the Bank constructor
public Bank (int sizeIn) throws Exception { if (sizeIn < 0) { throw new Exception(); } else { list = new BankAccount[sizeIn]; total = 0; }
public Bank (int sizeIn) throws NegativeSizeException { if (sizeIn < 0) { throw new Exception(); } else { list = new BankAccount[sizeIn]; total = 0; }
public Bank (int sizeIn) throws NegativeSizeException { if (sizeIn < 0) { throw new NegativeSizeException(); } else { list = new BankAccount[sizeIn]; total = 0; }
Testing for the NegativeSizeException
public class BankProgram { public static void main(String[] args) { try { System.out.print(“Maximum number of accounts? “); size = EasyScanner.nextInt(); Bank myBank = new Bank(size); // rest of code here } catch (NegativeSizeException e) { System.out.println(e.getMessage()); System.out.println(“due to error in Bank constructor”); } catch (Exception e) { System.out.println(“Some unforseen error”); e.printStackTrace(); } // rest of code here } }
Re-throwing exceptions
public Bank (int sizeIn) throws NegativeSizeException { if (sizeIn < 0) { throw new NegativeSizeException(); } else { list = new BankAccount[sizeIn]; total = 0; }
public Bank (int sizeIn) throws NegativeSizeException { if (sizeIn ≥ 0) { throw new NegativeSizeException(); } else { list = new BankAccount[sizeIn]; total = 0; }
public Bank (int sizeIn) throws NegativeSizeException { if (sizeIn ≥ 0) { list = new BankAccount[sizeIn]; total = 0; } else { throw new NegativeSizeException(); }
public Bank (int sizeIn) throws NegativeSizeException { try { list = new BankAccount[sizeIn]; total = 0; } catch ( ? ) { throw new NegativeSizeException(); }
public Bank (int sizeIn) throws NegativeSizeException { try { list = new BankAccount[sizeIn]; total = 0; } catch ( NegativeArraySizeException e ) { throw new NegativeSizeException(); }
Practical Work
public class Exceptions { public static void main(String[ ] args) { int[ ] someArray = {12,9,3,11}; int position = getPosition(); display (someArray, position); System.out.println("End of program" ); } private static int getPosition() { System.out.println("Enter array position to display"); String positionEntered = EasyScanner.nextString(); return Integer.parseInt(positionEntered); } private static void display (int[ ] arrayIn, int posIn) { System.out.println("Item at this position is: " + arrayIn[posIn]); } } return Integer.parseInt(positionEntered); System.out.println("Item at this position is: " + arrayIn[posIn]); NumberFormatException ArrayIndexOutOfBoundsException
a)Re-write main so that it catches any exceptions it may now throw by displaying a message on the screen indicating the exception thrown.
public static void main(String[ ] args) { int[ ] someArray = {12,9,3,11}; int position = getPosition(); display (someArray, position); System.out.println("End of program" ); }
public static void main(String[ ] args) { try { int[ ] someArray = {12,9,3,11}; int position = getPosition(); display (someArray, position); } System.out.println("End of program" ); } // catches go here
b) Add an additional catch clause in main to catch any unaccounted for exceptions (within this catch clause print out the stack trace of the exception).
public static void main(String[ ] args) { try { int[ ] someArray = {12,9,3,11}; int position = getPosition(); display (someArray, position); } System.out.println("End of program" ); } // old catches as before
public static void main(String[ ] args) { try { int[ ] someArray = {12,9,3,11}; int position = getPosition(); display (someArray, position); } System.out.println("End of program" ); } // old catches as before // add additional catch clause Catches all exceptions not caught so far.
c) Create your own exception class InvalidPositionException (make this a checked exception).
public class InvalidPositionException { }
public class InvalidPositionException { } Make this a checked exception
public class InvalidPositionException { } extends Exception
public class InvalidPositionException { } extends Exception // add two constructors here
d)Re-write the display method so that it throws the InvalidPositionException from a catch block.
private static void display (int[ ] arrayIn, int posIn) { System.out.println("Item at this position is: " + arrayIn[posIn]); }
private static void display (int[ ] arrayIn, int posIn) throws InvalidPositionException { System.out.println("Item at this position is: " + arrayIn[posIn]); }
private static void display (int[ ] arrayIn, int posIn) throws InvalidPositionException { try { System.out.println("Item at this position is: " + arrayIn[posIn]); } catch ( ? ) { // code here }
e)Re-write main to take account of this amended display method.
public static void main(String[ ] args) { try { int[ ] someArray = {12,9,3,11}; int position = getPosition(); display (someArray, position); } System.out.println("End of program" ); } // old catches
public static void main(String[ ] args) { try { int[ ] someArray = {12,9,3,11}; int position = getPosition(); display (someArray, position); } System.out.println("End of program" ); } // modify catches so this new exception is caught