A Network Programming Lecture by Steven Choy
Lecture Overview: Introduction to exception handling - Java's way of handling exceptional events - Java's exception handling mechanism - Java's exception objects - Checked exceptions and unchecked exceptions - How and when to throw an exception - When should we use the throws keyword - Advantages of using Java's way to handle exceptions - Class exercises
Introduction
- In a program, some events are considered exceptional or unusual.
- Some examples of exceptional events that may occur at runtime:
- I/O errors such as file not found
- Array index out of bounds
- Divided by zero
- Out of memory
- An exceptional event will disrupt the normal execution flow of a program, and it is the responsibility of programmers to deal with exceptional events that may be encountered in their programs.
- However, consider the situation when a program has to check for each possible error value after every method call.
- This can make the program cluttered with error-handling codes, thereby making it difficult to read and maintain.
Java's way
- Java’s exception mechanism is a lot cleaner than having to check for error values after every method call.
- Java has five keywords dedicated to exception handling:
try, catch, finally, throws, throw
- try-catch-finally — to catch exceptions
- throws — to declare exceptions
- throw — to throw exceptions
- The general form of using try-catch-finally is:
try {
statements in which exceptions may happens
} catch (ExceptionType1 ex) {
statements to handle ExceptionType1
} catch (ExceptionType2 ex) {
statements to handle ExceptionType2
}
} finally {
statements that are always executed
}
Java's exception handling mechanism
try {
....
} catch (Exception e) {
...
}
try {
...
} catch (IOException e) {
...
} catch (Exception e) {
...
}
try {
...
} finally {
...
}
- The following fragments are not valid
try {
....
}
try {
...
} catch (Exception e) {
...
} catch (IOException e) {
...
}
try {
...
} finally {
...
} finally {
...
}
Java's exception objects
- In Java, an exception is represented by an instance of a subclass of
Throwable.
- Example: integer division by zero results in an
ArithmeticException
- There are many predefined exception classes in the Java standard library.
(Predefined exception classes in the Java standard library. The classes which are shaded are unchecked exceptions, while the others are checked exceptions.)
- Exceptions of type Error and its subclasses represent very critical errors in the Java virtual machine, such as virtual machine errors or out of memory. Your programs probably need not handle these errors since they happen infrequently and they cannot be recovered by the application logic.
- RuntimeException and its subclasses represent runtime errors that can happen during the execution of the program. They often indicate errors in the program’s logic such as numeric errors and out-of-bound errors. For example, ArithmeticException in the previous program is a subclass of RuntimeException and the program shall implement some logic to check that the integer values are valid for the division. This is particularly important if the values came from some external sources such as from the user via the console input or from a file. Therefore, if a RuntimeException happens when your program runs, you should carefully examine the error message and modify the program’s logic to cater for such an error.
Checked exceptions and unchecked exceptions
- In Java, exceptions are classified into two categories
- Unchecked exceptions
- RuntimeException, Error and their subclasses
- These exceptions are named ‘unchecked’ because the compiler does not require the handling of them in programs.
- In other words, a program that does not implement logic to handle unchecked exceptions can still be compiled.
- Checked exceptions
- Exception and its subclasses, excluding RuntimeException and RuntimeException’s subclasses.
- Java checks these exceptions during compilation and requires the program to handle them.
- For example, a program that opens a file without handling the IOException cannot be compiled.
How and when to throw an exception
throw exceptionObject;
- Example: a program may create an exception and then throw it
Exception ex = new UnsupportedOperationException("Input too large");
throw ex;
- or do the same thing in one line of code:
throw new UnsupportedOperationException("Input too large");
- When should we throw an exception in an method?
Typically, if a method finds an error and the method itself is not an appropriate place to handle the error according to the program’s design, then it throws an exception to signal the caller of the method hoping that the caller is in a better position to handle the error. On the other hand, if the method can handle the error itself, it is better to do so rather than throwing an exception.
- Exceptions are often thrown from the Java standard library and caught in the user application programs.
For example, the constructor of the library class FileInputStream may throw an exception if the specified file is not found, and the application program is supposed to implement a try-catch-finally construct to catch and handle FileNotFoundException according to the program design. You may frequently refer to the Java API documentation for the exceptions that happen in different library classes and methods.
When should we use the throws keyword
- The
throws keyword declares the exception(s) that a method may throw.
- Situation One: It is used to specify exceptions that will be generated and passed to the caller.
public methodB2 throws IOException, VelException {
String str = null;
str = " .. ";
if( ... ) {
throw new IOException(str);
}
str = " .. ";
if( ... ) {
throw new velException(str, velocity);
}
- Situation Two: It is used to specify exceptions that will not be handled in a method.
public class LazyClass
{
public static void main(String[] args) throws Exception
{
. . .
}
}
Advantages of using Java's way to handle exceptions
- Java’s exception mechanism has three advantages over traditional error management techniques:
- It separates error handling code from ‘regular’ code in a clear manner.
- It is able to propagate errors up the call stack.
- It can group error types and carry out error differentiation so that you don’t need to explicitly deal with every individual error.
Class Exercises
- Exercise 1: State the output of the following programs. You can compile and then execute the programs to see the output if you are in doubt about the results.
public class FirstException {
public static void change(int[] course) {
System.out.println("Start Change");
course[10] = 1;
System.out.println("End Change");
}
public static void main(String[] args) {
int[] students = new int[5];
try {
System.out.println("Start Try");
change(students);
System.out.println("After change");
}
catch (ArrayIndexOutOfBoundsException e) {
System.err.println("OutOfBounds: " + e.getMessage());
}
System.out.println("After try ");
}
}
- Exercise 2: State the output of the following programs. You can compile and then execute the programs to see the output if you are in doubt about the results.
public class SecondException {
public static void doubleChange(int[] course) {
System.out.println("Start Double Change");
course[10] = 1;
System.out.println("End Double Change");
}
public static void change(int[] course) {
System.out.println("Start Change");
doubleChange(course);
System.out.println("End Change");
}
public static void main(String args[]) {
int[] students = new int[5];
try {
System.out.println("Start Try");
change(students);
System.out.println("After change");
} catch (ArrayIndexOutOfBoundsException e) {
System.err.println("OutOfBounds: " + e.getMessage());
}
System.out.println("After try ");
}
}
- Exercise 3: State the output of the following programs. You can compile and then execute the programs to see the output if you are in doubt about the results.
public class ThirdException {
public static void change(int[] course) {
try {
System.out.println("Start Change");
course[10] = 1;
System.out.println("End Change");
} catch (ArrayIndexOutOfBoundsException e) {
System.err.println("Change Catch: " + e.getMessage());
}
}
public static void main(String args[]) {
int[] students = new int[5];
try {
System.out.println("Start Try");
change(students);
System.out.println("After change");
} catch (ArrayIndexOutOfBoundsException e) {
System.err.println("Main Catch: " + e.getMessage());
}
System.out.println("After try ");
}
}
- Exercise 4: Suppose that
statement2 causes an exception in the following try-catch block. Answer the following questions.
try {
statement1;
statement2;
statement3;
}
catch (Exception1 ex1) {
statement4;
}
catch (Exception2 ex2) {
statement5;
}
statement6;
- (1) Will statement3 be executed?
- (2) If the exception is not caught, will statement6 be executed?
- (3) If the exception is caught in the catch clause, will statement6 be executed?
- (4) If the exception is passed to the caller, will statement6 be executed?
- Exercise 5: What is displayed on the console when the following program is run?
class Question5 {
public static void main(String[] args) {
try {
System.out.println("Welcome to MT811");
return;
}
finally {
System.out.println("Statement in finally block");
}
}
}
- Exercise 6: What is displayed on the console when the following program is run?
class Question6 {
public static void main(String[] args) {
try {
System.out.println("Welcome to MT811");
int i = 0;
int y = 2/i;
System.out.println(“Statement after calculation”);
}
catch (RuntimeException ex) {
System.out.println("Statement in catch block");
}
finally {
System.out.println("Statement in finally block");
}
System.out.println(“End of the block”);
}
}
Thanks for Reading
If you would rather like to have this lecture note in printed format, please click the print action link in the top right corner.
If you find any problem in this lecture note, please feel free to tell Steven via steven@findaway.hk.