Module 4
Module 4
Exception Handling
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 code.
Java exception handling is managed via five keywords: try, catch, throw, throws, and finally.
Program statements that want to monitor for exceptions are contained within a try block. If an exception
occurs within the try block, it is thrown. Then code can catch this exception (using catch) and handle it in
some rational manner.
To manually throw an exception, use the keyword throw. Any exception that is thrown out of a method must
be specified as such by a throws clause. Any code that absolutely must be executed after a try block completes
is put in a finally block.
This is the general form of an exception-handling block:
Exception Types:
All exception types are subclasses of the built-in class Throwable. Thus, Throwable is at the top of the
exception class hierarchy. Immediately below Throwable are two subclasses that partition exceptions into two
distinct branches. One branch is headed by Exception. This class is used for exceptional conditions that user
programs should catch.
There is an important subclass of Exception, called RuntimeException. Exceptions of this type are
automatically defined for the programs that is written and include things such as division by zero and invalid
array indexing.
Exceptions of type Error are typically created in response to catastrophic failures that cannot usually be
handled by program.
Uncaught Exceptions:
This small program includes an expression that intentionally causes a divide-by-zero error:
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 Exc0 to stop, because once an exception has been
thrown, it must be caught by an exception handler and dealt with immediately.
The stack trace will always show the sequence of method invocations that led up to the error. For example,
here is another version of the preceding program that introduces the same error but in a method separate from
main( ):
Once an exception is thrown, program control transfers out of the try block into the catch block. Put
differently, catch is not “called,” so execution never “returns” to the try block from a catch. Thus, the line
"This will not be printed." is not displayed. Once the catch statement has executed, program control continues
with the next line in the program following the entire try / catch mechanism.
A try and its catch statement form a unit. The scope of the catch clause is restricted to those statements
specified by the immediately preceding try statement. A catch statement cannot catch an exception thrown by
another try statement (except in the case of nested try statements)
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,specify two or more catch clauses, each catching a different type of exception.
This program will cause a division-by-zero exception if it is started with no command-line arguments, since
a will equal zero. It will survive the division if you provide a command-line argument, setting a to something
larger than zero. But it will cause an ArrayIndexOutOfBoundsException, since the int array c has a length of
1, yet the program attempts to assign a value to c[42].
When multiple catch statements is used, it is important to remember that exception subclasses must come
before any of their superclasses. This is because a catch statement that uses a superclass will catch exceptions
of that type plus any of its subclasses. Thus, a subclass would never be reached if it came after its superclass.
Since ArithmeticException is a subclass of Exception, the first catch statement will handle all Exception-
based errors, including ArithmeticException. This means that the second catch statement will never execute.
To fix the problem, reverse the order of the catch statements.
Here is the previous program recoded so that the nested try block is moved inside the method nesttry( ):
The output of this program is identical to that of the preceding example.
throw:
It is possible for a 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.
There are two ways to obtain a Throwable object: using a parameter in a catch clause or creating one
with the new operator.
Here is a sample program that creates and throws an exception. The handler that catches the exception
rethrows it to the outer handler.
throws:
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. To do this by including a throws clause in
the method’s declaration. A throws clause lists the types of exceptions that a method might throw.
Here, exception-list is a comma-separated list of the exceptions that a method can throw.
Following is an example of an incorrect program that tries to throw an exception that it does not catch. Because
the program does not specify a throws clause to declare this fact, the program will not compile.
To make this example compile, need to make two changes. First, to declare that throwOne( ) throws
IllegalAccessException. Second, main( ) must define a try / catch statement that catches this exception. The
corrected example is shown here:
finally:
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.
Here is an example program that shows three methods that exit in various ways, none without executing their
finally clauses:
Java’s Built-in Exceptions:
Inside the standard package java.lang, Java defines several exception classes. A few have been used by the
preceding examples. The most general of these exceptions are subclasses of the standard type
RuntimeException.
In the language of Java, these are called unchecked exceptions because the compiler does not check to see if
a method handles or throws these exceptions.
Java’s Unchecked RuntimeException Subclasses Defined in java.lang:
Java’s Checked Exceptions Defined in java.lang:
Exceptions defined by java.lang that must be included in a method’s throws list if that method can generate
one of these exceptions and does not handle it itself. These are called checked exceptions.
THREADS
Thread(Flow of Execution):
• Multitasking(Executing several task simultaneously)
• Process Based(Each task is separate independent process eg.OS-level)
• Thread Based(Each task is the part of the same program
eg.Programmatic level)
• Two ways to define a thread
• By extending Thread class
• By implementing Runnable Interface
Output:
• By default, the name of the main thread is main. Its priority is 5, which is the default value, and main
is also the name of the group of threads to which this thread belongs. A thread group is a data structure
that controls the state of a collection of threads as a whole.
• The sleep( ) method causes the thread from which it is called to suspend execution for the specified
period of milliseconds. Its general form is shown here:
static void sleep(long milliseconds) throws InterruptedException
The number of milliseconds to suspend is specified in milliseconds. This method may throw an
InterruptedException.
The sleep( ) method has a second form, shown next, which allows you to specify the period in terms of
milliseconds and nanoseconds:
static void sleep(long milliseconds, int nanoseconds) throws InterruptedException
This second form is useful only in environments that allow timing periods as short as nanoseconds.
• set the name of a thread by using setName( )
• can obtain the name of a thread by calling getName( )
final void setName(String threadName) final String
getName( )
Here, threadName specifies the name of the thread.
Creating a Thread:
Create a thread by instantiating an object of type Thread. Java defines two
ways in which this can be accomplished:
• By implement the Runnable interface.
• By can extend the Thread class, itself. Implementing
Runnable:
The easiest way to create a thread is to create a class that implements the Runnable interface. Runnable
abstracts a unit of executable code. To implement Runnable, a class need only implement a single method
called run( ), which is declared like this:
public void run( )
After create a class that implements Runnable, instantiate an object of type Thread from within that class.
Thread defines several constructors.
Thread(Runnable threadOb, String threadName)
In this constructor, threadOb is an instance of a class that implements the Runnable interface. This defines
where execution of the thread will begin. The name of the new thread is specified by threadName.
After the new thread is created, it will not start running until you call its start( ) method, which is declared
within Thread. In essence, start( ) initiates a call to run( ). The start( ) method is shown here:
void start( )
Output:
Extending Thread:
The second way to create a thread is to create a new class that extends Thread, and then to create an
instance of that class. The extending class must override the run( ) method, which is
the entry point for the new thread. As before, a call to start( ) begins execution of the new thread.
This program generates the same output as the preceding version. As the child thread is created by
instantiating an object of NewThread, which is derived from Thread.
Notice the call to super( ) inside NewThread. This invokes the following form of the Thread constructor:
public Thread(String threadName)
Here, threadName specifies the name of the thread. Choosing an
Approach:
The Thread class defines several methods that can be overridden by a derived class. Of these methods, the
only one that must be overridden is run( ).It will not be overriding any of Thread’s other methods, it is
probably best simply to implement Runnable. Also, by implementing Runnable, your thread class does not
need to inherit Thread, making it free to inherit a different class.
Synchronization:
When two or more threads need access to a shared resource, they need some way to ensure that the resource
will be used by only one thread at a time. The process by which this is achieved is called synchronization
Using Synchronized Methods :
To enter an object’s monitor, just call a method that has been modified with the synchronized keyword. While
a thread is inside a synchronized method, all other threads that try to call it (or any other synchronized method)
on the same instance have to wait.
Output:
To fix the preceding program, to serialize access to call( ). That is, must restrict its access to only one thread
at a time. To do this, you simply need to precede call( )’s definition with the keyword synchronized, as shown
here:
Deadlock:
A special type of error that you need to avoid that relates specifically to multitasking is deadlock, which
occurs when two threads have a circular dependency on a pair of synchronized objects.
Deadlock is a difficult error to debug for two reasons:
• In general, it occurs only rarely, when the two threads time-slice in just the right
way.
• It may involve more than two threads and two synchronized objects.
Output:
The following example illustrates how the wait( ) and notify( ) methods that are inherited from Object can
be used to control the execution of a thread. Let us consider its operation. The NewThread class contains a
boolean instance variable named suspendFlag, which is
used to control the execution of the thread. It is initialized to false by the constructor. The run( ) method
contains a synchronized statement block that checks suspendFlag. If that variable is true, the wait( ) method
is invoked to suspend the execution of the thread. The mysuspend( ) method sets suspendFlag to true. The
myresume( ) method sets suspendFlag to false and invokes notify( ) to wake up the thread. Finally, the main(
) method has been modified to invoke the mysuspend( ) and myresume( ) methods.
Obtaining a Thread’s State:
The current state of a thread by calling the getState( ) method defined by Thread. It is shown here:
Thread.State getState( )
It returns a value of type Thread.State that indicates the state of the thread at the time at which the call
was made.
State is an enumeration defined by Thread.
Here are the values that can be returned by getState( ):
Thread states:
Given a Thread instance, use getState( ) to obtain the state of a thread. For example, the following sequence
determines if a thread called thrd is in the RUNNABLE state at the time getState( ) is called:
It is important to understand that a thread’s state may change after the call to getState( ). Thus, depending on
the circumstances, the state obtained by calling getState( ) may not reflect the actual state of the thread only
a moment later.