Unit Iii
Unit Iii
Inheritance
Inheritance: Inheritance is the process by which objects of one class acquire the
properties of objects of another class. Inheritance supports the concept of hierarchical
classification. A deeply inherited subclass inherits all of the attributes from each of its
ancestors in the class hierarchy.
Most people naturally view the world as made up of objects that are related to each other in a
hierarchical way.
Inheritance: A new class (subclass, child class) is derived from the existing class (base class,
parent class).
Super class: In Java a class that is inherited from is called a super class.
Sub class: The class that does the inheriting is called as subclass. It inherits all of the
instance variables and methods defined by the superclass and add its own, unique
elements.
The “extends” keyword indicates that the properties of the super class name are extended
to the subclass name. The sub class now contains its own variables and methods.
Types of Inheritance are used to show the Hierarchical abstractions. They are:
Single Inheritance
Multiple Inheritance
Hierarchical Inheritance
Multilevel Inheritance
Hybrid Inheritance.
Single Inheritance: Simple Inheritance is also called as single Inheritance. Here one
subclass is deriving from one super class.
A B
import java.io.*;
class A class Inh
{ {
void display() public static void main(String
{ args[])
System.out.println("hi”); {
B b=new B();
} b.display();
}
class B extends A }
{ }
void display()
{ Output:
D:\>javac Inh.java
System.out.println("hello"); D:\>java Inh
hello
}
}
Multiple Inheritance: Deriving one subclass from more than one super classes is called
multiple inheritance.
INTERFACE1 INTERFACE2
A B
(Animal) (Bird)
IMPLEMENTS
SUBCLASS (InterfaceDemo2)
In multiple inheritance, sub class is derived from multiple super classes. If two super
classes have same name for their members, then which member is inherited into the sub
class is the main confusion in multiple inheritance. This is the reason; Java does not
support the concept of multiple inheritance. This confusion is reduced by using
multiple interfaces to achieve the concept of multiple inheritance.
Interface syntax:
access interface name
{
return-type method-name1(parameter-list);
return-type method-name2(parameter-list);
type varname1 = value;
type varname2 = value;
// ...
return-type method-nameN(parameter-list);
type varnameN = value;
}
By default all the methods in an interface must be abstract and public. If we do not
mention these keywords the JVM will treat all these methods as public and
abstract implicitly.
All the constants are treated as public, final and static.
Example:
public class InterfaceDemo2
interface Animal implements Animal, Bird
{ {
public abstract void moves(); public void moves()
} {
System.out.println("animal move on
interface Bird land");
{ }
void fly();
}
JAVA Programming Page 4
UNIT III Inheritance
Hierarchical Inheritance: Only one base class but many derived classes.
SUPERCLASS
Figure
EXTENDS
Rectangle Triangle
SUBCLASS
Example:
Rectangle(double a, double b)
class Figure {
{ super(a, b);
double dim1; }
double dim2;
// override area for rectangle
Figure(double a, double b) double area()
{ {
dim1 = a; System.out.println("Inside Area for
dim2 = b; Rectangle.");
} return dim1 * dim2;
}
double area() }
{
System.out.println("Inside Figure"); class Triangle extends Figure
} {
}
Multilevel Inheritance: In multilevel inheritance the class is derived from the derived
class.
A B C
Example: {
// Create a super class. System.out.println("Inside B's
class A constructor.");
{ }
A() }
{ // Create another subclass by extending
System.out.println("Inside A's B.
constructor."); class C extends B
} {
} C()
// Create a subclass by extending class {
A. System.out.println("Inside C's
class B extends A constructor.");
{ }
B() }
class CallingCons
{ Output :
public static void main(String args[]) D:\>javac CallingCons.java
{ D:\>java CallingCons
C c = new C(); Inside A's constructor.
} Inside B's constructor.
} Inside C's constructor.
A
HIERARCHICAL
B C
D
MULTIPLE
Super Uses: Whenever a subclass needs to refer to its immediate super class, it
can do so by the use of the keyword super.
Super has the two general forms.
super (args-list) : calls the Super class’s constructor.
super.member: To access a member of the super class that has been hidden by a
member of a subclass. Member may be variable or method.
1. Accessing the super class constructor: super (parameter_list) calls the super class
constructor. The statement calling super class constructor should be the first one in sub
class constructor.
Example program for super can be used to refer super class constructor as: super
(values)
class Figure super(a,b);
{ }
double dim1; double area()
double dim2; {
Figure(double a, double b) System.out.println("Inside area for
{ triangle");
dim1=a; return dim1*dim2/2;
dim2=b; }
} }
} class FindAreas
class Rectangle extends Figure {
{ public static void main(String args[])
Rectangle(double a,double b) {
{ Rectangle r=new Rectangle(9,5);
super(a,b);//calls super class constructor Triangle t=new Triangle(10,8);
} System.out.println("area is"+r.area());
double area() System.out.println("area is"+t.area());
{ }
System.out.println("Inside area for }
rectangle"); Output:
return dim1*dim2; D:\>javac FindAreas.java
} D:\>java FindAreas
} Inside area for rectangle
class Triangle extends Figure area is45.0
{ Inside area for triangle
Triangle(double a,double b) area is40.0
{
2. Accessing the member of a super class: The second form of super acts somewhat
like this, except that it always refers to the superclass of the subclass in which it is
used.
Here, member can be either a method or an instance variable. This second form of super
is most applicable to situations in which member names of a subclass hide members by
the same name in the superclass. Consider this simple class hierarchy:
JAVA Programming Page 8
UNIT III Inheritance
Abstract classes:
A method with body is called concrete method. In general any class will have all
concrete methods.
Abstraction refers to the act of representing essential features without including the
background details or explanations. Classes use the concept of abstraction and are
defined as a list of attributes and methods to operate on these attributes. They
encapsulate all the essential features of the objects that are to be created since the classes
use the concept of data abstraction they are known as Abstract Data Types.
lang package
Object class
Object class is implicitly (automatically) imported into our source code, because it is in
“lang” package. lang package is also implicitly imported into every java program.
Object class reference can store any reference of any object. This means that a reference
variable of type Object can refer to an object of any other class.
Classes are usually declared final for either performance or security reasons.
Final with variables: Final variables work like constants of C-language that can’t be
altered in the whole program. That is, final variables once created can’t be changed and
they must be used as it is by all the program code.
{ B b=new B();
b.display();
super.display(); }
System.out.println("hello"); }
} Output: [Error]
public static void main(String args[]) Display() in B cannot override display()
{ in A; overridden method is final.
Final with classes: If we want the class not be sub-classed (or extended) by any other
class, declare it final. Classes declared final can not be extended. That is, any class can
use the methods of a final class by creating an object of the final class and call the
methods with the object (final class object).
Example program: {
import java.io.*; Demo1 d=new Demo1();
final class Demo1 d.display();
{ }
public void display() }
{ Output:
System.out.println("hi"); D:\>javac Demo3.java
} Demo3.java:9: cannot inherit from final
} Demo1
public class Demo3 extends Demo1 public class Demo3 extends Demo1
{ ^
public static void main(String args[]) 1 error
Polymorphism: Polymorphism came from the two Greek words ‘poly’ means
many and ‘morphs’ means forms. If the same method has ability to take more than
one form to perform several tasks then it is called polymorphism. It is of two types:
Dynamic polymorphism(Runtime polymorphism)
Static polymorphism(Compile time polymorphism)
Dynamic Polymorphism: The polymorphism exhibited at run time is called
dynamic polymorphism. In this dynamic polymorphism a method call is linked with
method body at the time of execution by JVM. Java compiler does not know which
method is called at the time of compilation. This is also known as dynamic binding
or run time polymorphism. Method overloading and method overriding are
examples of Dynamic Polymorphism in Java.
Method Overloading: Writing two or more methods with the same name with
different parameters is called method over loading. In method overloading JVM
understands which method is called depending upon the difference in the method
parameters. The difference may be due to the following:
Ø There is a difference in the no. of parameters.
void add (int a, int b) void add (int a, int b, int c)
Ø There is a difference in the data types of parameters.
void add (int a, float b) void add (double a, double b)
Ø There is a difference in the sequence of parameters.
void swap (int a, char b) void swap (char a, int b)
// overloading of methods --------- class OverLoad
Dynamic polymorphism {
class Sample public static void main(String[] args)
{ {
void add(int a, int b) Sample s=new Sample ( );
{ s.add (20, 25);
System.out.println ("sum of two="+ s.add (20, 25, 30);
(a+b)); }
} }
void add(int a, int b, int c) Output:
{ D:\>javac OverLoad.java
System.out.println ("sum of three="+ D:\java OverLoad
(a+b+c)); sum of two=45
} sum of three=75
}
Achieving method overloading & method overriding using instance methods is an example of
dynamic polymorphism.
Achieving method overloading & method overriding using static methods is an example of
Static Polymorphism.
//Static Polymorphism
class Animal
{
static void move ()
{
System.out.println ("Animals can move");
}
}
class Dog extends Animal
{
static void move ()
{
System.out.println ("Dogs can walk and run");
}
}
public class StaticPoly
{
public static void main(String args[])
{
Animal.move ();
Dog.move ();
}
}
Output:
D:\>javac StaticPoly.java
D:\>java StaticPoly
Animals can move
Dogs can walk and run
Interfaces: An interface is defined much like as an abstract class (it contains only method
declarations).It contains constants and method declarations.
Syntax:
accessspecifier interface interfacename
{
return-type method-name1(parameter-list);
return-type method-name2(parameter-list);
datatype varname1 = value;
datatype varname2 = value;
// ...
return-type method-nameN(parameter-list);
datatype varnameN = value;
}
When no access specifier is included, then default access results, and the interface is only
available to other members of the package in which it is declared. When it is declared as public,
the interface can be used by any other code. In this case, the interface must be the only public
interface.
Note: that the methods are declared have no bodies. They end with a semicolon after the
parameter list. They are, essentially, abstract methods; there can be no default implementation
of any method specified within an interface. Each class that includes an interface must
implement all of the methods.
Variables can be declared inside of interface declarations. They are implicitly final and static,
meaning they cannot be changed by the implementing class. They must also be initialized. All
methods and variables are implicitly public.
Example:
public interface animal
{
void display();
}
Implementing Interfaces:
Once an interface has been defined, one or more classes can implement that interface.
To implement an interface, include the implements clause in a class definition, and then
create the methods defined by the interface.
Syntax:
class classname [extends superclass] [implements interface [,interface...]]
{
// class-body
}
If a class implements more than one interface, the interfaces are separated with a comma. If a
class implements two interfaces that declare the same method, then the same method will be
used by clients of either interface. The methods that implement an interface must be declared
public. Also, the type signature of the implementing method must match exactly the type
signature specified in the interface definition.
Example:
public interface Animal
{ {
void eat(); Dog d=new Dog();
} d.eat();
class Dog implements Animal Animal a;
{ a=d;
void eat() a.eat();
{ }
System.out.println(“Dog eats Output::
Chicken”); D:\javac InterfaceDemo.java
} D:\java InterfaceDemo
} Dog eats Chicken
public class InterfacDemo Dog eats Chicken
{
public static void main(String
args[])
Variables in Interfaces:
You can use interfaces to import shared constants into multiple classes
by simply declaring an interface that contains variables that are
initialized to the desired values.
When you implement that interface in a class all of those variable
names will be in scope as constants. (This is similar to using a header
file in C to create a large number of #define constants or const
declarations.)
If an interface contains no methods, then any class that includes such
an interface doesn’t actually implement anything.
It is as if that class was importing the constant fields into the class
name space as final variables.
Example:
Classes in Java have its particular fields and methods. Each object is an
instance of a class, and follows the class prototype that defines the
variables and methods common to all objects of a certain kind. Each
instance of a class must be instantiated, after it is declared, unlike in C++.
This is usually done with the keyword "new". Classes may have
inheritance from other classes, as they do in C++, meaning they inherit all
the properties of the parent class. This is usually done with the
keyword "extends".
Variables All the variables are instance by All the variables are static final by
default unless otherwise default, and a value needs to be
specified assigned at the time of definition
Methods All the methods should be All the methods are abstract by
having a definition unless default and they will not have a
decorated with an abstract definition.
keyword
Package: Packages are containers for classes that are used to keep
the class name space compartmentalized. Packages are stored in a
hierarchical manner and are explicitly imported into new class definitions.
Packages are of two types Built-in packages and User-defined packages.
Built-in packages are already available in java language which contains
classes, interfaces and methods for the programmer to perform any task.
Ex: java.lang, java.util etc.
User-defined packages can be created by the users of java which can be
imported to other classes and used exactly in the same way as the Built-in
packages.
Creating a Package: To create a package is quite easy: simply
include a package command as the first statement in a Java source file.
Any classes declared within that file will belong to the specified package.
The package statement defines a name space in which classes are
stored.
If you omit the package statement, the class names are put into the
default package, which has no name.
D:\Sub>javac –d . Addition.java
The preceding command means create a package (-d) in the current
directory (.) and store Addition.class file there in the package. The package
name is specified in the program as pack.
So the Java compiler creates a directory in D:\Sub with the name as pack
and stores Addition.class there. Observe it by going to pack sub directory
which is created in D:\Sub. So, our package with Addition class is ready.
D:\Sub>java pack.Addition
The preceding command is used for executing the Additon class file which
is in pack package.
Sum= 125.3530000
Example:
package pack;
public class Subtraction
{
private double d1,d2;
public Subtraction(double a,double b)
{
d1=a; d2=b;
}
public void subtract()
{
System.out.println(“Difference= “+(d1-d2));
}
public static void main(String args[])
{
Subtraction s=new Subtraction(123.123,23.123);
a.sum();
}
}
D:\Sub>javac pack/Subtraction.java
The preceding command is used for compiling the Subtraction.java
program which is in pack package. This command generates a class file
and stores in pack package.
D:\Sub>java pack.Subtraction
The preceding command is used for executing the Subtraction class file
which is in pack package.
Difference= 100.00
Accessing a Package
Java provides many levels of protection to allow fine-grained control
over the visibility of variables and methods within classes, subclasses,
and packages.
Classes and packages are both means of encapsulating and containing
the name space and scope of variables and methods.
Packages act as containers for classes and other subordinate packages.
Classes act as containers for data and code.
The class is Java’s smallest unit of abstraction. Because of the interplay
between classes and packages, Java addresses four categories of
visibility for class members:
Subclasses in the same package
Non-subclasses in the same package
Subclasses in different packages
Classes that are neither in the same package nor subclasses
The four access specifiers, private, public, protected and default,
provide a variety of ways to produce the many levels of access required
by these categories.
Example: System.out.println("base
Save as Protection.java in constructor");
package p1: System.out.println("n = " + n);
package p1; System.out.println("n_pri = " +
public class Protection n_pri);
{ System.out.println("n_pro = " +
int n = 1; n_pro);
public Protection() }
{ }
System.out.println("derived }
constructor");
System.out.println("n = " + n);
D:\>javac p1/Derived.java
D:\>javac p1/SamePackage.java
Output: D:\>javac Demo.java
D:\>javac p1/Protection.java D:\>java Demo
base constructor n_pub = 4
n=1 base constructor
n_pri = 2 n=1
n_pro = 3 n_pri = 2
n_pub = 4 n_pro = 3
base constructor n_pub = 4
n=1 same package constructor
n_pri = 2 n=1
n_pro = 3 n_pro = 3
n_pub = 4 n_pub = 4
derived constructor
n=1
n_pro = 3
Save as Protection2.java in }
package p2: Save as OtherPackage.java in
package p2; package p2:
public class Protection2 extends package p2;
p1.Protection public class OtherPackage
{ {
public Protection2() public OtherPackage()
{ {
System.out.println("derived other p1.Protection p = new
package constructor"); p1.Protection();
System.out.println("n_pro = " + System.out.println("other
n_pro); package constructor");
System.out.println("n_pub = " + System.out.println("n_pub = " +
n_pub); p.n_pub);
} }
} {
Main method class for package Protection2 ob1 = new
p2: save in current directory Protection2();
import p2.*; OtherPackage ob2 = new
public class Demo OtherPackage();
{ }
Output: n_pro = 3
D:\>javac p2/OtherPackage.java n_pub = 4
D:\>javac p2/Protection2.java base constructor
D:\>javac DemoTwo.java n=1
D:\>java DemoTwo n_pri = 2
base constructor n_pro = 3
n=1 n_pub = 4
n_pri = 2 other package constructor
n_pro = 3 n_pub = 4
n_pub = 4
derived other package constructor
UNIT V Exception Handling and Multi-Threading
Importing Packages
Java includes the import statement to bring certain classes, or entire packages, into
visibility.
Once imported, a class can be referred to directly, using only its name.
The import statement is a convenience to the programmer and is not technically needed
to write a complete Java program.
If you are going to refer to a few dozen classes in your application, however, the import
statement will save a lot of typing.
In a Java source file, import statements occur immediately following the package
statement (If it exists) and before any class definitions.
This is the general form of the import statement:
import pkg1[.pkg2].(classname|*);
Example:
import java.util.Date;
import java.io.*;
import java.util.*;
1) import pack.Addition;
2) import pack.*;
In statement 1, only the Addition class of the package pack is imported into the program
and in statement 2, all the classes and interfaces of the package pack are available to the
program.
If a programmer wants to import only one class of a package say BufferedReader of java.io
package, he can write:
import java.io.BufferedReader;
This is straight and the Java compiler links up the BufferedReader of java.io package with
the program. But, if he writes import statement as:
import java.io.*;
In this case, the Java compiler conducts a search for BufferedReader class in java.io
package, every time it is used in the rest of the program. This increases load on the compiler
and hence compilation time increases. However, there will not be any change in the
runtime.
Exception Handling
Errors in a Java Program: There are two types of errors, compile time errors and
run time errors.
Compile time errors: These are syntactical errors found in the code, due to which a
program fails to compile. For example, forgetting a semicolon at the end of a Java
statement, or writing a statement without proper syntax will result in compile-time
error. Detecting and correcting compile-time errors is easy as the Java compiler
displays the list of errors with the line numbers along with their description. The
programmer can go to the statements, check them word by word and line by line to
understand where he has committed the errors.
Run time errors: The run time errors are the errors that occur at the run-time of the
program and cause the abnormal termination of the program. The run time errors are
called exceptions. There are the three types of runtime errors.
Input errors: Input errors occur if the user provides unexpected inputs to the program.
For example, if the program wants an integer and the user provides it the string value.
These errors can be prevented from occurring by prompting the user to enter the
correct type of values.
System errors: System errors or hardware errors occur rarely. These errors occur due
to unreliable system software or hardware malfunctions. These errors are beyond a
programmer’s control.
Logical errors: logical errors occur if the program is logically incorrect. These errors
either generate incorrect results or terminate program abnormally. For example, a
program for adding two numbers requires an addition operator (+), if the program
supplies subtraction operator (-) then this generates the incorrect results. To debug
these errors the program must be scanned to check the logical statements.
Exception handling means to handle the exceptions by the programmer to recover the
computer from malfunction due to exceptions.
In Java, exception handling is managed via five keywords: try, catch, throw, throws, and
finally.
try: The try block is said to monitor the statements enclosed within it and defines the
scope of any exception associated with it. It detects the exceptions.
catch: The catch clause contains a series of legal Java statements. These statements are
executed if and when the exception handler is invoked. It holds an exception. Catch is
known as exception handler which is a piece of code used to deal with the exceptions,
either to fix the error or abort execution in a sophisticated way.
throw: To manually throw an exception ,use the keyword throw.
throws: Any exception that is thrown out of a method must be specified as such by a
throws clause.
finally: Any code that absolutely must be executed after a try block completes is put in
a finally block. After the exception handler has run, the runtime system passes control
to the finally block.
Syntax:
try
{
// block of code to monitor for errors
}
Exception Hierarchy: All exception types are subclasses of the built-in class
Throwable, where Throwable is subclass for ‘Object’. Thus, Throwable is at the top of the
exception class hierarchy. Immediately below Throwable, there 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. This is also the class that you will subclass to create your own user
defined exception types. There is an important subclass of Exception, called
RuntimeException. Exceptions of this type are automatically defined for the programs that
you write and include things such as division by zero and invalid array indexing.
The other branch is topped by Error, which defines exceptions that are not expected to be
caught under normal circumstances by your program. Exceptions of type Error are used by
the Java run-time system to indicate errors having to do with the run-time environment,
itself. Stack overflow is an example of such an error.
Object: Object is a super class of all classes (user defined, pre-defined classes) directly
or indirectly. Because it is included in the lang package.
Throwable: Throwable is super class of Errors and Exceptions in java. Throwable is
derived from the object class.
Error: Error is a class. This type of errors cannot be handled.
Exception: An abnormal event in a program is called Exception.
Programmer should compulsorily handle the checked exceptions in code, otherwise code
will not be compiled i.e. the code which may cause checked exception must be specified in
try-catch block or throws clause containing the list of checked exception is provided to the
method declaration.
Example:
import java.io.*; {
class CEDemo
Unchecked Exceptions: Exceptions which are checked at run time. A java method does not
require declaring that it will throw any of the run-time exception. Unchecked exceptions are
RuntimeException and any of its subclasses and Class Error and its subclasses also are
unchecked. Unchecked runtime exceptions represent conditions that reflect errors in
program's logic and cannot be reasonably recovered from at run time. With an unchecked
exception, compiler doesn't force programmers either to catch the exception or declare it in
a throws clause.
Example: System.out.println("okay");
public class REDemo }
{ }
static public void main(String args[]) Output:
{ D:\Seshu\Except>javac CEDemo.java
int d[]={1,2}; D:\Seshu\Except>java REDemo
d[3]=99; Exception in thread "main"
int a=5,b=0,c; java.lang.ArrayIndexOutOfBoundsExcept
c=a/b; ion: 3
System.out.println("c is:"+c); at REDemo.main(CEDemo.java:6)
Exception handling provides the following advantages over ''traditional'' error management
techniques:
Separating Error Handling Code from ``regular'' one: provides a way to separate
the details of what to do when something out-of-the-ordinary happens from the normal
logical flow of the program code;
Propagating Errors up the Call Stack: lets the corrective action to be taken at a
higher level. This allows the corrective action to be taken in the method that calling that
one where an error occurs;
Grouping Error Types and Error Differentiation: Allows to create similar
hierarchical structure for exception handling so groups them in logical way.
Termination Model: In this model of exception handling, the programmer will have to
explicitly invoke the same method in which the error has occurred, and was transferred to
the catch block, so that the error can be handled. The explicit invocation is required,
because few programming languages that use this kind of model do not allow the control to
return back to the point, where the error has occurred.
Presumptive Model: In this model of exception handling, the programmer will not have to
explicitly invoke the same method in which the error has occurred, and was transferred to
the catch block, so that the error can be handled. Because the programming languages that
use this kind of model will allow the control to return back to the point, where the error has
occurred.
The first question that arises is how or where to indicate presumption. Basically, there are
only two possibilities:
Firstly, the decision whether to resume or not can be made at the raising point, i.e. by the
raise statement itself. This implies that a language would have to offer two different raise
statements: one for the termination model and another one for resumption, i.e. where the
handler always “returns” and resumes execution at the raising point.
The main advantage of this possibility is that there is no doubt about the continuation of the
control flow. In particular, it is already known in the raising context, whether a handler will
resume or not.
Usually only after having tried to cure the cause of an exception, we can say, whether the
attempt was successful or not. Therefore, only the handler of an exception can decide,
whether it could cure the cause for an exception or not. This knowledge is essential, because
resumption only makes sense with the motivation to cure the cause for the exception before
resuming normal execution.
Therefore, a programmer has to decide that the respective handler should indicate whether
to terminate or to resume.
Uncaught Exceptions:
The following program illustrates what happens when you don’t handle the exception when
it is raised. This small program includes an expression that intentionally causes a divide-by-
zero error:
class Exc0
{
public static void main(String args[])
{
int d = 0;
int a = 42 / d;
}
}
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. In this example, no exception handlers are specified, so the
exception is caught by the default handler provided by the Java run-time system. Any
exception that is not caught by your program will ultimately be processed by the default
handler. 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.
Notice how the class name, Exc0; the method name, main; the filename, Exc0.java; and
the line number, 4, are all included in the simple stack trace. Also, notice that the type of
exception thrown is a subclass of Exception called ArithmeticException, which more
specifically describes what type of error happened.
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( ):
class Exc1
{
static void subroutine()
{
int d = 0;
int a = 10 / d;
}
public static void main(String args[])
{
Exc1.subroutine();
}
}
The resulting stack trace from the default handler shows how the entire call stack is
displayed:
java.lang.ArithmeticException: / by zero
at Exc1.subroutine(Exc1.java:6)
at Exc1.main(Exc1.java:10)
As you can see, the bottom of the stack is main’s line 7, which is the call to subroutine( ),
which caused the exception at line 4. The call stack is quite useful for debugging, because it
pinpoints the precise sequence of steps that led to the error.
try: Although the default exception handler provided by the Java run-time system is useful
for debugging, a programmer will usually want to handle an exception by themself. Doing
so provides two benefits.
First, it allows you to fix the error.
Second, it prevents the program from automatically terminating.
To handle run-time errors and monitor the results, simply enclose the code inside a try
block. If an exception occurs within the try block, it is handled by the appropriate exception
handler (catch block) associated with the try block. If there are no exceptions to be thrown,
then try will return the result executing block. A try should have one (or more) catch blocks
or one finally block or both. If neither is present, a compiler error occurs which says try
without catch or finally.
catch: A catch clause is a group of java statements, enclosed in braces { } which are used to
handle a specific exception that has been thrown. Catch clauses should be placed after the
try block i.e. catch clause follows immediately after the try block.
A catch clause is specified by the keyword catch followed by a single argument within
parenthesis (). The argument type in a catch clause is form the Throwable class or one of its
subclasses.
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)
The statements that are protected by try must be surrounded by curly braces. (That is,
they must be within a block.) We cannot use try on a single statement.
The goal of most well-constructed catch clauses should be to resolve the exceptional
condition and then continue on as if the error had never happened.
To illustrate how easily this can be done, the following program includes a try block and a
catch clause that processes the ArithmeticException generated by the division-by-zero
error:
class Exc2
{
public static void main(String args[])
{
int d, a;
try
{ // monitor a block of code.
d = 0;
a = 42 / d;
System.out.println("This will not be printed.");
}
catch (ArithmeticException e)
{ // catch divide-by-zero error
System.out.println("Division by zero.");
}
System.out.println("After catch statement.");
}
}
This program generates the following output:
Division by zero.
After catch statement.
Notice that the call to println( ) inside the try block is never executed. Once an exception
is thrown, program control transfers out of the try block into the catch block.
can display this description in a println ( ) statement by simply passing the exception as an
argument. For example, the catch block in the preceding program can be rewritten like this:
catch (ArithmeticException e)
{
System.out.println("Exception: " + e);
a = 0; // set a to zero and continue
}
When this version is substituted in the program, and the program is run, each divide-by-zero
error displays the following message:
Exception: java.lang.ArithmeticException: / by zero
In some cases, more than one exception could be raised by a single piece of code. To handle
this type of situation, we 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. The following example traps two different exception types:
Example:
class MultiCatch
{
public static void main(String args[])
{
try
{
int a = args.length;
System.out.println("a = " + a);
int b = 42 / a;
int c[] = { 1 };
c[42] = 99;
}
catch(ArithmeticException e)
{
System.out.println("Divide by 0: " + e);
}
catch(ArrayIndexOutOfBoundsException e)
{
Thus, a subclass would never be reached if it came after its superclass. Further, in Java,
unreachable code is an error. For example, consider the following program:
/* this program contains an error. A subclass must come before its superclass in a series of
catch statements. If not, unreachable code will be created and a compile-time error will
result.*/
If we try to compile this program, we will receive an error message stating that the second
catch statement is unreachable because the exception has already been caught. 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.
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. Here is an example that uses nested try statements:
Example:
class NestTry
{
public static void main(String args[])
{
try
{
int a = args.length;
/* If no command-line args are present, the following statement will generate a divide-by-
zero exception. */
int b = 42 / a;
System.out.println("a = " + a);
try
{ // nested try block
/* If one command-line arg is used,
then a divide-by-zero exception
will be generated by the following code. */
if(a==1) a = a/(a-a); // division by zero
C:\>java NestTry
Divide by 0: java.lang.ArithmeticException: / by zero
C:\>java NestTry One
a=1
Divide by 0: java.lang.ArithmeticException: / by zero
C:\>java NestTry One Two
a=2
Array index out-of-bounds:
java.lang.ArrayIndexOutOfBoundsException:42
throw: ‘throw’ is a java keyword used in exception handling. Generally a try block
checks for arrival of error and when an error occurs it throws the error and it is caught by
the catch statement and then appropriate action will take place. Only the expressions thrown
by the java run-time system are being caught, but throw keyword allows a program to throw
an exception explicitly.
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.
Example:
class ThrowDemo
{
static void demoproc()
{
try
{
throw new NullPointerException("demo");
}
catch(NullPointerException e)
{
System.out.println("Caught inside demoproc.");
throw e; // rethrow the exception
}
}
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. The exception is then rethrown.
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. We 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. This is necessary for all exceptions, except those
OOP Through JAVA NEC, CSE Dept. Page 49
UNIT V Exception Handling and Multi-Threading
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.
Syntax:
returntype method-name(parameter-list) throws exception-list
{
// body of method
}
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.
finally:
Whenever an exception occurs, the exception affects the flow of execution of the program.
Sometimes some blocks may be bypassed by exception handling. For example, if a method
opens a file upon entry and closes it upon exit, then you will not want the code that closes
the file to be bypassed by the exception-handling mechanism. The finally keyword is
designed to address this contingency.
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.
Any time a method is about to return to the caller from inside a try/catch block, via an
uncaught exception or an explicit return statement, the finally clause is also executed
just before the method returns.
This can be useful for closing file handles and freeing up any other resources that might
have been allocated at the beginning of a method with the intent of disposing of them
before returning.
The finally clause is optional. However, each try statement requires at least one catch or
a finally clause.
Here is an example program that shows three methods that exit in various ways, none
without executing their finally clauses:
// Demonstrate finally. {
class FinallyDemo System.out.println("procB's finally");
{ }
// Through an exception out of the }
method.
static void procA()
{ // Execute a try block normally.
try static void procC()
{ {
System.out.println("inside procA"); try
throw new RuntimeException("demo"); {
} System.out.println("inside procC");
finally }
{ finally
System.out.println("procA's finally"); {
} System.out.println("procC's finally");
} }
// Return from within a try block. }
static void procB() public static void main(String args[])
{ {
try try
{ {
System.out.println("inside procB"); procA();
return; }
} catch(Exception e)
finally {
In this example, procA( ) prematurely breaks out of the try by throwing an exception.
The finally clause is executed on the way out. procB( )’s try statement is exited via a
return statement.
The finally clause is executed before procB( ) returns. In procC( ), the try
statementexecutes normally, without error. However, the finally block is still executed.
NOTE: If a finally block is associated with a try, the finally block will be executed upon
conclusion of the try.
Creating own Exception Sub Classes: Although Java’s built-in exceptions handle
most common errors, we will probably want to create our own exception types to handle
situations specific to our applications. This is quite easy to do: just define a subclass of
Exception (which is, of course, a subclass of Throwable). Our subclasses don’t need to
actually implement anything—it is their existence in the type system that allows us to use
them as exceptions.
The Exception class does not define any methods of its own. It does, of course, inherit those
methods provided by Throwable. Thus, all exceptions, including those that you create, have
the methods defined by Throwable available to them. They are shown in Table.
We may also wish to override one or more of these methods (shown in table) in exception
classes that you create.
Exception defines 2 constructors.
Exception( )
Exception(String msg)
The first form creates an exception that has no description. The second form lets us specify
a description of the exception. Although specifying a description when an exception is
created is often useful, sometimes it is better to override toString( ). Here’s why: The
version of toString( ) defined by Throwable (and inherited by Exception) first displays the
name of the exception followed by a colon, which is then followed by your description. By
overriding toString( ), we can prevent the exception name and colon from being displayed.
This makes for a cleaner output, which is desirable in some cases.
The following example declares a new subclass of Exception and then uses that subclass to
signal an error condition in a method. It overrides the toString( ) method, allowing a
carefully tailored description of the exception to be displayed.