CS F213 Objected Oriented Programming Labsheet 6
Spring 2024
Java Exceptions
A Java exception is an object that describes an exceptional (that is, error) condition that has occurred in a piece of code. When an exceptional condition arises, an object representing that exception is created and thrown in the method that caused the error. That method may choose to handle the exception itself, or pass it on. Either way, at some point, the exception is caught and processed. Exceptions can be generated by the Java run-time system, or they can be manually generated by your code
.
Uncaught Exceptions
When the Java run-time system detects the attempt to divide by zero
, it constructs a new exception object and then throws this exception. This causes the execution of Main
to stop, because once an exception has been thrown, it must be caught by an exception handle
r and dealt with immediately. In this example, we haven’t supplied any exception handlers of our own, so the exception is caught by the default handler provided by the Java run-time system
. The default handler displays a string describing the exception, prints a stack trace
from the point at which the exception occurred, and terminates the program.Here is the exception generated when this example is executed:
The stack trace will always show the sequence of method invocations that led up to the error, therefore the call stack is quite useful for debugging, because it pinpoints the precise sequence of steps that led to the error.
Using try and catch
Although the default exception handler provided by the Java run-time system is useful for debugging, you will usually want to handle an exception yourself. Doing so provides two benefits.
First, it allows you to fix the error.
Second, it prevents the program from automatically terminating.
To guard against and handle a run-time error, simply enclose the code that you want to monitor inside a try
block. Immediately following the try block, include a catch
clause that specifies the exception type that you wish to catch.
Once an exception is thrown, program control transfers out of the try block into the catch block and the execution never returns to the try block.
Output
Displaying a Description of an Exception
Throwable overrides the toString( ) method (defined by Object) so that it returns a string containing a description of the exception. You can display this description in a println( ) statement by simply passing the exception as an argument.
Multiple catch Clauses
In some cases, more than one exception could be raised by a single piece of code. To handle this type of situation, you can specify two or more catch clauses, each catching a different type of exception. When an exception is thrown, each catch statement is inspected in order, and the first one whose type matches that of the exception is executed. After one catch statement executes, the others are bypassed, and execution continues after the try / catch block.
Depending on the type of Exception thrown the respective cath block will be executed.
Nested try Statements
The try statement can be nested. That is, a try statement can be inside the block of another try. Each time a try statement is entered, the context of that exception is pushed on the stack. If an inner try statement does not have a catch handler for a particular exception, the stack is unwound and the next try statement’s catch handlers are inspected for a match. This continues until one of the catch statements succeeds, or until all of the nested try statements are exhausted. If no catch statement matches, then the Java run-time system will handle the exception.
Output
Custom Exceptions
Java throw Keyword
So far, you have only been catching exceptions that are thrown by the Java run-time system. However, it is possible for your program to throw an exception explicitly, using the throw
statement. The general form of throw is shown here:
throw ThrowableInstance;
Here, ThrowableInstance must be an object of type Throwable or a subclass of Throwable
. Primitive types, such as int or char, as well as non-Throwable classes, such as String and Object, cannot be used as exceptions. There are two ways you can obtain a Throwable object: using a parameter in a catch
clause or creating one with the new
operator. The flow of execution stops immediately after the throw statement; any subsequent statements are not executed. The nearest enclosing try
block is inspected to see if it has a catch statement that matches the type of exception. If it does find a match, control is transferred to that statement. If not, then the next enclosing try
statement is inspected, and so on. If no matching catch is found, then the default exception handler halts the program and prints the stack trace.
Output
This program gets two chances to deal with the same error. First, main( ) sets up an exception context and then calls demoproc( ). The demoproc( ) method then sets up another exception-handling context and immediately throws a new instance of NullPointerException, which is caught on the next line.
Here, new is used to construct an instance of NullPointerException. Many of Java’s built-in run-time exceptions have at least two constructors: one with no parameter and one that takes a string parameter. When the second form is used, the argument specifies a string that describes the exception. This string is displayed when the object is used as an argument to print( ) or println( ). It can also be obtained by a call to getMessage( ), which is defined by Throwable.
Java throws Keyword
If a method is capable of causing an exception that it does not handle, it must specify this behavior so that callers of the method can guard themselves against that exception. This is necessary for all exceptions, except those of type Error or RuntimeException, or any of their subclasses. All other exceptions that a method can throw must be declared in the throws clause. If they are not, a compile-time error will result.
Example
Output
Java finally Keyword
finally
creates a block of code that will be executed after a try /catch block has completed and before the code following the try/catch block. The finally block will execute whether or not an exception is thrown.
If an exception is thrown, the finally block will execute even if no catch statement matches the exception. The finally clause is optional. However, each try statement requires at least one catch or a finally clause.
Output
Here as you can see the the exception is thrown so the statements except the ones written in catch
block will not be executed. But the ones inside finally
are executed first and then the exception is shown. Notice how "rest of the code..."
is not printed.
Creating Your Own Exception Subclasses
Although Java’s built-in exceptions handle most common errors, you will probably want to create your own exception types to handle situations specific to your applications. This is quite easy to do: define a subclass of Exception
Exception defines four
public constructors. Two support chained exceptions, described in the next section. The other two are shown here:
Exception( )
Exception(String msg)
The first form creates an exception that has no description. The second form lets you specify a description of the exception.
Example
Chained Exceptions
Chained Exceptions allows to relate one exception with another exception, i.e one exception describes cause of another exception. For example, consider a situation in which a method throws an ArithmeticException because of an attempt to divide by zero but the actual cause of exception was an I/O error which caused the divisor to be zero. The method will throw only ArithmeticException to the caller. So the caller would not come to know about the actual cause of exception.
Constructors Of Throwable class
Which support chained exceptions in java :
Throwable(Throwable cause) :- Where cause is the exception that causes the current exception.
Throwable(String msg, Throwable cause) :- Where msg is the exception message and cause is the exception that causes the current exception.
Methods Of Throwable class
Which support chained exceptions in java :
getCause() method :- This method returns actual cause of an exception.
initCause(Throwable cause) method :- This method sets the cause for the calling exception.
Output
Example 2
output
As you can see, the RuntimeException object is printed to the console with a message indicating that there was an error caused by division by zero. The stack trace of the original ArithmeticException object is also included as the cause of the exception.
By chaining exceptions, you can provide more information about the original cause of an exception, which can be helpful in debugging and troubleshooting.
Exercises
Exercise 1
Design a simple calculator program that performs basic division operations. Implement a class named Calculator with a method named divide that takes two integers as parameters and performs the division operation. Ensure that the method handles the scenario of attempting to divide by zero.
In the main method, create an instance of Calculator, take user input for two integers, and call the divide method to demonstrate the functionality of the class. If the user attempts to divide by zero, catch and handle the ArithmeticException and print the message "Cannot divide by zero."
Sample Input
Sample Output
Exercise 2
Create a program to manage exam scores of students using an array.
Student Class:
Create a class named Student with the following attributes and methods:
Attributes:
name
(String): Represents the name of the student.
score
(int): Represents the exam score of the student.
Methods:
Constructor
to initialize the name and score attributes.
Getter methods
for name and score.
StudentManager Class:
Implement a class named StudentManager with an an array of Student objects with max size taken by the user
to store the students and having the following methods
:
addStudent
(String name, int score): If current size of array is less than the max size add a student with the given name and exam score to the array else print "Cannot add more students."
getAverageScore
(): Calculate and return the average exam score of all students in the array. getStudentScore
(String name): Retrieve and return the exam score of a specific student by providing their name (You can use a linear search and string.equals() method for this)
Main Class: In the main method, create an instance of StudentManager, add students with their scores, and demonstrate the functionality of the class. Ensure to handle the following scenarios:
If a user tries to get the average score when no students are added, catch and handle the ArithmeticException
and print the message "EXCEPTION-- No students in the list. Cannot calculate average."
If a user tries to retrieve the exam score of a student who is not in the list, catch and handle the NullPointerException
and print the message "EXCEPTION-- Student not found in the list."
Sample Input/Output
Exercise 3
Design a program to process financial transactions in a banking system. Implement a class called TransactionProcessor
with a constructor
for setting the initialAmount
method named processTransaction
that takes a transaction amount as input and makes the transaction giving the updated balance. The program should handle various exceptions that might occur during the transaction processing.
Consider the following requirements:
If the transaction amount is negative, throw a custom exception NegativeAmountException
with the message "Transaction amount cannot be negative."
If the transaction amount is greater than the account balance, throw a custom InsufficientBalanceException
with the message "Insufficient balance. Transaction declined."
If the transaction amount is not a valid numeric value, throw a NumberFormatException
with the message "Invalid transaction amount format."
If any other unexpected exception occurs during processing, catch it and display a generic error message "An unexpected error occurred. Please try again later."
Handle these exceptions with separate catch blocks in the processTransaction method.
In the main
method, create an instance of TransactionProcessor, take user input for initial balance and transaction amount, and call the processTransaction method to demonstrate the exception handling.
Ensure that the program provides meaningful error messages for different scenarios and gracefully handles exceptions without crashing.
Note: You need to create the custom exceptions (NegativeAmountException and InsufficientBalanceException) as well.
Sample Input/Output
Last updated