Professional Documents
Culture Documents
E - NOTES
Unit No Title
IV Generic Programming
V Concurrent Programming
CS55 PROGRAMMING PARADIGMS
UNIT I
Java History
Java is a general-purpose object oriented programming language developed by Sun
Microsystems of USA in 1991. Originally called oak by James Gosling, one of the inventors if
the language. This goal had a strong impact on the development team to make the language
simple, portable, highly reliable and powerful language. Java also adds some new features.
While C++ is a superset of C. Java is neither a superset nor a subset of C or C++.
C++
C Java
Abstraction
An essential element of object-oriented programming is abstraction. Abstraction refers to
the act of representing essential features without including the background details or
explanations.
For example, people do not think of a car as a set of tens of thousands of individual parts.
They think of it as a well-defined object with its own unique behavior. This abstraction allows
people to use a car to drive to the grocery store without being overwhelmed by the complexity of
the parts that form the car. They can ignore the details of how the engine, transmission, and
braking systems work. Instead they are free to utilize the object as a whole.
Page 3 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
a) Encapsulation
Encapsulation is the mechanism that binds together code and the data it manipulates, and
keeps both safe from outside interference and misuse.
For example, shifting gears does not turn on the headlights in car, because it encapsulates
the information about all process.
In Java the basis of encapsulation is the class. A class defines the structure and behavior
(data and code) that will be shared by a set of objects. For this reason, objects are sometimes
referred to as instances of a class. Thus, a class is a logical construct and an object has physical
reality.
b) Inheritance
Inheritance is the process by which one object acquires the properties of another object.
This is important because it supports the concept of hierarchical classification. For example
Bird
Attributes:
Feathers
Lay eggs
Attributes: Attributes:
----------- -----------
---------- -----------
The bird 'robin ' is a part of the class 'flying bird' which is again a part of the class 'bird'.
The concept of inheritance provides the idea of reusability.
c) Polymorphism
Polymorphism means the ability to take more than one form. Subclasses of a class can
define their own unique behaviors and yet share some of the same functionality of the parent
class.
Shape
Draw()
Class
A class is a blueprint or prototype from which objects are created. The entire set of data
and code of an object can be made of a user defined data type with the help of a class. We can
create any number of objects for the same class.
Page 4 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
For example the construction of building requires a plan. Without plan we can't construct
building. Here plan acts as class. Building acts as object. Using the same plan we can build any
number of buildings. In the same way we can create any number of objects for the same class.
Class tells the objects state and behavior. Basically class tells what the object should have.
Object
Object is an instance of class. Object is real world entity which has state, identity and
behavior. It may represent a person, a place, a bank account, a table of data or any item that the
program has to handle.
1. Standalone applications that have no initial context such as a pre-existing main window
2. Applets for WWW programming
Execution begins when you launch the java virtual machine and tell it to find a particular class.
After finding the class, java executes the enclosed main() method with signature:
Program Execution
Create a source code file using a text editor. The source code is then compiled using the
java compiler javac. Each java program is converted into one or more class files. The content of
the class file is a set of instructions called bytecode to be executed by Java Virtual Machine
(JVM).Java introduces bytecode to create platform independent program. JVM is an interpreter
for bytecode which accepts java bytecode and produces result.
Page 5 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
3. Language Basics
a) Comments
Java comments make your code easy to understand, modify and use. Java supports three
different types of comment styles.
1.Everything between initial slash asterisk and ending asterisk-slash is ignored by the java
compiler.(/**/)
2.Double slash (//)mark is ignored by java compiler.
3.Everything between initial slash asterisk - asterisk and ending asterisk-slash is ignored
by the java compiler and another program called JAVADOC.EXE that ships with the
JDK uses these comments to construct HTML documentation files that describe your
packages, classes and methods as well as all the variables used. (/***/)
b) Data Types
Java defines eight simple (or elemental) types of data: byte, short, int, long, char, float,
double, and boolean. These can be put in four groups:
Integers - This group includes byte, short, int, and long, which are for whole valued
signed numbers.
Floating -point numbers- This group includes float and double, which represent numbers
with fractional precision.
Characters - This group includes char, which represents symbols in a character set, like
letters and numbers.
Boolean - This group includes boolean, which is a special type for representing true/false
values.
c) Variables
Variables are locations in memory in which values can be stored. They have a name, a
type, and a value. Before you can use a variable, you have to declare it. After it is declared, you
can then assign values to it.
Java actually has three kinds of variables: instance variables, class variables, and local
variables.
Instance variables are used to define attributes or the state for a particular object.
Class variables are similar to instance variables, except their values apply to all
that classs instances (and to the class itself) rather than having different values
for each object.
Local variables are declared and used inside method definitions, for example, for
index counters in loops, as temporary variables, or to hold values that you need
only inside the method definition itself.
Although all three kinds of variables are declared in much the same ways, class and
instance variables are accessed and assigned in slightly different ways from local variables.
Scope
Page 6 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Declaring Variables
For variable declarations, Java syntax is similar to C and C++ syntax. For native types,
the syntax may be summarized as follows:
One word type name.
A list of variable names, separated by commas.
An optional initializer following each variable name.
Terminated by semicolon.
The following are examples of variable declarations:
This line of Java code declares a 32-bit integer variable named i:
int i;
This line declares two 32-bit integer variables named i and j:
int i , j;
This line declares i and j as above and initializes them:
int i=3, j=4;
d) Statements
Java, like C, is an expression-based language. Expressions must always appear in the
context of statements. A statement consists of an expression followed by a terminating semicolon
(;).
Statements can be made up of zero or more expressions, provided that their combination
makes syntactic sense. Expressions (except for the return value of void methods) have a value
and a type. A terminating semicolon (e.g., 27;) turns it into a legal statement even though it does
not do anything useful. A simple statement consists of an expression and a semicolon. The
semicolon is a required terminator.
4. Defining Class
The class is at the core of Java. It is the logical construct upon which the entire Java
language is built because it defines the shape and nature of an object. As such, the class forms
the basis for object-oriented programming in Java. The entire set of data and code of an object
can be made of a user defined data type with the help of a class. Thus, a class is a template for an
object, and an object is an instance of a class.
// ...
type instance-variableN;
type methodname1(parameter-list){
// body of method
}
type methodname2(parameter-list) {
// body of method
}
// ...
type methodnameN(parameter-list) {
// body of method
}
}
Here is a class called Box that defines three instance variables: width, height, and depth.
Currently, Box does not contain any methods (but some will be added soon).
class Box
{
double width;
double height;
double depth;
}
Instantiating a class
Class declaration only creates a template; it does not create an actual object. To create a
Box object, you will use a statement like the following:
Box mybox = new Box(); // create a Box object called mybox
The new operator allocates space for the new object, calls a class constructor and returns
a reference to the object.
It should be noted that the class and its constructor have the same name.
After this statement executes, mybox will be an instance of Box. Each time you create an
instance of a class, you are creating an object that contains its own copy of each instance variable
defined by the class. Thus, every Box object will contain its own copies of the instance variables
width, height, and depth. To access these variables, you will use the dot (.) operator. The dot
operator links the name of the object with the name of an instance variable. For example, to
assign the width variable of mybox the value 100, you would use the following statement:
mybox.width = 100;
This statement tells the compiler to assign the copy of width that is contained within the
mybox object the value of 100.
5. Methods
Classes usually consist of two things: instance variables and methods.
This is the general form of a method:
Type name (parameter-list)
Page 8 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
{
// body of method
}
Type specifies the type of data returned by the method. This can be any valid type,
including class types that you create. If the method does not return a value, its return type must
be void.
The name of the method is specified by name. This can be any legal identifier other than
those already used by other items within the current scope.
The parameter-list is a sequence of type and identifier pairs separated by commas.
Parameters are essentially variables that receive the value of the arguments passed to the method
when it is called. If the method has no parameters, then the parameter list will be empty.
Methods that have a return type other than void return a value to the calling routine using
the following form of the return statement:
return value;
Here, value is the value returned.
class BoxDemo3
{
public static void main(String args[]) {
Box mybox1 = new Box();
Box mybox2 = new Box();
// assign values to mybox1's instance variables
mybox1.width = 10;
mybox1.height = 20;
mybox1.depth = 15;
/* assign different values to mybox2's instance variables */
mybox2.width = 3;
mybox2.height = 6;
mybox2.depth = 9;
// display volume of first box
mybox1.volume();
// display volume of second box
Page 9 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
mybox2.volume();
}
}
This program generates the following output.
THE JAVA LANGUAGE
Volume is 3000.0
Volume is 162.0
The mybox1.volume() invokes the volume( ) method on mybox1. That is, it calls
volume( ) relative to the mybox1 object, using the objects name followed by the dot operator.
Thus, the call to mybox1.volume( ) displays the volume of the box defined by mybox1, and the
call to mybox2.volume( ) displays the volume of the box defined by mybox2. Each time
volume( ) is invoked, it displays the volume for the specified box.
6. Access specifiers
Encapsulation provides another important attribute: access control. Through
encapsulation, you can control what parts of a program can access the members of a class. By
controlling access, you can prevent misuse.
How a member can be accessed is determined by the access specifier that modifies its
declaration. Java supplies a rich set of access specifiers. Some aspects of access control are
related mostly to inheritance or packages. (A package is, essentially, a grouping of classes.)
Javas access specifiers are
Public
Private
Protected
default access level.
Public
When a member of a class is modified by the public specifier, then that member can be
accessed by any other code. So main( ) has always been preceded by the public specifier.
Classes can be declared public. A public class is accessible by any other Java class. A
class that is not declared public has package access, which means that only classes within the
same package may access it. Class members labeled public are accessible to all other classes.
Private
When a member of a class is specified as private, then that member can only be accessed
by other members of its class.
Class members can be declared public or private to enforce proper encapsulation. Certain
data elements or methods that are necessary for the classs internal behavior should be protected
from access by outside classes. These should be declared private. A class member that has been
declared as private will remain private to its class. It is not accessible by any code outside its
class, including subclasses.
Protected
Any member that is declared protected is accessible only by a class that is derived from
the current class or is in the same package as the containing class.
Page 10 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
7. Static Members
Static Variables
If you define a field as static, then there is only one such field per class. In contrast, each
object has its own copy of all instance fields. For example, let's suppose we want to assign a
unique identification number to each employee. We add an instance field id and a static field
nextId to the Employee class:
class Employee
{
...
private int id;
private static int nextId = 1;
}
Now, every employee object has its own id field, but there is only one nextId field that is shared
among all instances of the class. Let's put it another way. If there are one thousand objects of the
Employee class, then there are one thousand instance fields id, one for each object. But there is a
single static field nextId. Even if there are no employee objects, the static field nextId is present.
It belongs to the class, not to any individual object.
Constants
Static variables are quite rare. However, static constants are more common. For example,
the Math class defines a static constant:
public class Math
{
...
public static final double PI = 3.14159265358979323846;
Page 11 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
...
}
You can access this constant in your programs as Math.PI. If the keyword static had been
omitted, then PI would have been an instance field of the Math class. That is, you would need an
object of the Math class to access PI, and every object would have its own copy of PI. Another
static constant that you have used many times is System.out. It is declared in the System class as:
public class System
{
...
public static final PrintStream out = . . .;
...
}
As we mentioned several times, it is never a good idea to have public fields because everyone
can modify them. However, public constants (that is, final fields) are ok. Since out has been
declared as final, you cannot reassign another print stream to it:
out = new PrintStream(. . .); // ERROR--out is final
Static Methods
Static methods are methods that do not operate on objects. For example, the pow method
of the Math class is a static method. The expression:
Math.pow(x, y)
Computes the power xy. It does not use any Math object to carry out its task. In other words, it
has no implicit parameter. In other words, you can think of static methods as methods that don't
have a this parameter. Because static methods don't operate on objects, you cannot access
instance fields from a static method. But static methods can access the static fields in their class.
Here is an example of such a static method:
public static int getNextId()
{
return nextId; // returns static field
}
To call this method, you supply the name of the class:
int n = Employee.getNextId();
Could you have omitted the keyword static for this method? Yes, but then you would need to
have an object reference of type Employee to invoke the method. You use static methods in two
situations:
1. When a method doesn't need to access the object state because all needed
parameters are supplied as explicit parameters (example: Math.pow)
2. When a method only needs to access static fields of the class (example:
Employee.getNextId)
8. Constructors
A constructor is a special method whose purpose is to construct and initialize objects.
Constructors always have the same name as the class name.
The constructor is automatically called immediately after the object is created, before the
new operator completes.
Box mybox1 = new Box();
Page 12 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
new Box( ) is calling the Box( ) constructor. When you do not explicitly define a
constructor for a class, then Java creates a default constructor for the class. The default
constructor automatically initializes all instance variables to zero.
There is an important difference between constructors and other methods: A constructor
can only be called in conjunction with the new operator. You can't apply a constructor to an
existing object to reset the instance fields.
Features of constructor
A constructor has the same name as the class.
A class can have more than one constructor.
A constructor may take zero, one, or more parameters.
A constructor has no return value.
A constructor is always called with the new operator.
a) Parameterized Constructors
Add parameters to the constructor.
class Box
{
double width;
double height;
double depth;
// This is the constructor for Box.
Box(double w, double h, double d) {
width = w;
height = h;
depth = d;
}
// compute and return volume
double volume() {
return width * height * depth;
}
}
class BoxDemo7
{
public static void main(String args[]) {
// declare, allocate, and initialize Box objects
Box mybox1 = new Box(10, 20, 15);
double vol;
// get volume of first box
vol = mybox1.volume();
System.out.println("Volume is " + vol);
}
}
The output from this program is shown here:
Volume is 3000.0
Page 13 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
b) this Keyword
this can be used inside any method to refer to the current object. this keyword has two
meanings:
to denote a reference to the implicit parameter
to call another constructor of the same class.
// A redundant use of this.
Box(double w, double h, double d)
{
this.width = w;
this.height = h;
this.depth = d;
}
c) Garbage Collection
The purpose of garbage collection is to identify and discard objects that are no longer
needed by a program so that their resources can be reclaimed and reused. A Java object is subject
to garbage collection when it becomes unreachable to the program in which it is used.
9. Finalizer method
Finalizer methods are like the opposite of constructor methods; whereas a constructor
method is used to initialize an object, finalizer methods are called just before the object is
garbage collected and its memory reclaimed. To create a finalizer method, include a method with
the following signature in your class definition:
void finalize() {
...
}
Inside the body of that finalize() method, include any cleaning up you want to do for that
object. Before you start using finalizer methods extensively in your Java programs, however, be
aware that finalizer methods have several very important restrictions. First of all, the finalizer
method is not guaranteed to be called until the objects memory is actually reclaimed, which may
be some time after youve removed all references to that object.
However, calling finalize() does not trigger an object to be garbage-collected. Only
removing all references to an object will cause it to be marked for deleting, and even then, Java
may or may not call the finalize() method itselfregardless of whether or not youve already
called it. Finalizer methods are best used for optimizing the removal of an objectfor example,
by removing references to other objects, by cleaning up things that object may have touched, or
for other optional behaviors that may make it easier for that object to be removed. In most cases,
you may not need to use finalize() at all.
Page 14 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
10. Arrays
An array is a group of like-typed variables that are referred to by a common name. Arrays
of any type can be created and may have one or more dimensions. A specific element in an array
is accessed by its index. Arrays offer a convenient means of grouping related information.
Arrays are ordered collections of identical objects that can be accessed via an index. Java
arrays have their own behavior that is encapsulated into their definition when the compiler
creates them. Since arrays are objects, array variables behave like class-type variables. It is
important to distinguish between the array variable and the array instance to which it refers.
Declaring an array only declares the array variable.
To instantiate the array, the new operator must be used with the [] operator to
enclose the array size. The array size can be any integer expression.
The following code declares an array variable and initializes it to null:
char data[] = null;
Array Constants
The declaration of an array must include its type, but not its size. An array initializer is
either a new expression that evaluates to the correct array type, or a list of initial element values
enclosed in { }. The following array constant provides initial values for its elements:
int[] int_array = {1, 3, 4, 15, 0};
Using Arrays
Array elements can be accessed using an index in square brackets [n], where the index
must be an integer. Arrays start with index number 0, not 1. The index can be thought of as an
offset from the beginning of the array. The index may not be less than zero or greater than the
declared size. If the array is declared size n, the index must be in the range 0 to n-1. Any attempt
to index an array with an illegal value will cause an exception to be thrown. All arrays have a
data field called length that indicates its size.
int ia[] = new int[100];
for (int i = 0; i < ia.length; i++)
{
Page 15 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
ia[i] = i * i;
}
public static void arraycopy (Object src, int src_position, Object dst, int dst_position, int
length)
The method copies elements from the given source array, beginning at the specified
position to the destination array at the specified position. It copies the number of elements
specified by the length argument. The destination array must already be allocated. Any type of
array may be copied. If range exceeds bounds of either array, a run-time error results.
Arrays in Java are in between a class and a data type although they are implemented as a
class internally by Java.
a) One-Dimensional Arrays
A one-dimensional array is a list of like-typed variables. Array is created by following steps.
1. Create an array variable of the desired type. The general form of a one dimensional array
declaration is
type var-name[ ];
2. Allocate memory for array.
Method1: The general form of new as it applies to one-dimensional arrays appears as
follows:
array-var = new type[size];
The elements in the array allocated by new will automatically be initialized to zero.
Method2: Arrays can be initialized when they are declared. The process is much the
same as that used to initialize the simple types. An array initializer is a list of comma-
separated expressions surrounded by curly braces. The commas separate the values of the
array elements. The array will automatically be created large enough to hold the number
of elements you specify in the array initializer. There is no need to use new. For example,
to store the number of days in each month, the following code creates an initialized array
of integers:
// An improved version of the previous program.
class AutoArray {
public static void main(String args[]) {
int month_days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31,30, 31 };
System.out.println("April has " + month_days[3] + " days.");
}
}
Page 16 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
b) Multidimensional Arrays
In Java, multidimensional arrays are actually arrays of arrays. These, as you might
expect, look and act like regular multidimensional arrays. However, as you will see, there are a
couple of subtle differences. To declare a multidimensional array variable, specify each
additional index using another set of square brackets. For example, the following declares a two-
dimensional array variable called twoD.
int twoD[][] = new int[4][5];
This allocates a 4 by 5 array and assigns it to twoD. Internally this matrix is implemented as an
array of arrays of int.
Page 17 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
An important attribute of the String class is that once a string object is constructed, its
value cannot change (note that it is the value of an object that cannot change, not that of a string
variable, which is just a reference to a string object). All String data members are private, and no
string method modifies the strings value.
String Methods
Although a string represents an array, standard array syntax cannot be used to inquire into
it. These are detailed in the below Table.
String Comparison
String comparison methods listed in below Table.
Page 18 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
String Searching
The String class also provides methods that search a string for the occurrence of a single
character or substring. These return the index of the matching substring or character if found, or -
1 if not found.
int indexOf (char ch)
int indexOf (char ch, int begin)
int lastIndexOf (char ch)
int lastIndexOf (char ch, int fromIndex)
int indexOf (String str)
int indexOf (String str, int begin)
int lastIndexOf (String str)
int lastIndexOf (String str, int fromIndex)
The following example shows the usage of these functions:
if (s1.indexOf (:) >= 0)
{
}
String suffix =
s1.substring (s1.lastIndexOf (.));
int spaceCount = 0;
int index = s1.indexOf ( );
while (index >= 0)
{
++spaceCount;
index = s1.indexOf ( , index + 1);
Page 19 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
}
int index = s1.indexOf (that);
String Concatenation
The String class provides a method for concatenating two strings:
String concat (String otherString)
The + and += String operators are more commonly used: The Java compiler recognizes the + and
+= operators as String operators. For each + expression, the compiler generates calls to methods
that carry out the concatentation. For each += expression, the compiler generates calls to
methods that carry out the concatenation and assignment.
12. Packages
Java allows you to group classes in a collection called a package. A class can use all
classes from its own package and all public classes from other packages.
You can import a specific class or the whole package. You place import statements at the
top of your source files (but below any package statements). For example, you can import all
classes in the java.util package with the statement:
import java.util.*;
Page 20 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
{
...
}
Package scope
Public features can be used by any class.
Private features can only be used by the class that defines them.
If you don't specify either public or private, then the feature (that is, the class, method, or
variable) can be accessed by all methods in the same package.
Class Comments
The class comment must be placed after any import statements, directly before the class
definition. Here is an example of a class comment:
/**
A <code>Card</code> object represents a playing card, such as "Queen of Hearts". A
card has a suit (Diamond, Heart, Spade or Club) and a value (1 = Ace, 2 . . . 10, 11 =
Jack, 12 = Queen, 13 = King).
*/
public class Card
Page 21 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
{
...
}
Method Comments
Each method comment must immediately precede the method that it describes. In
addition to the general-purpose tags, you can use the following tags:
@param variable description
This tag adds an entry to the parameters section of the current method. The description can
span multiple lines and can use HTML tags. All @param tags for one method must be kept
together.
@return description
This tag adds a returns section to the current method. The description can span multiple lines
and can use HTML tags.
@throws class description
Field Comments
You only need to document public fieldsgenerally that means static constants. For
example,
/**
The "Hearts" card suit
*/
public static final int HEARTS = 1;
General Comments
The following tags can be used in class documentation comments.
@author name
This tag makes an author entry. You can have multiple @author tags, one for each author.
@version text
Page 22 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
14. References
1. Cay S. Horstmann and Gary Cornell, Core Java: Volume I Fundamentals, Eighth
Edition, Sun Microsystems Press, 2008.
2. Herbert Schildt JAVA2:The complete reference Fifth Edition, McGraw-Hill/Osborne.
3. http://java.sun.com
Page 23 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
1. Inheritance
1.1. Member Access And Inheritance
1.2. Super Keyword
2. Class Hierarchy
3. Polymorphism
3.1. Overridden Methods
3.2. Overloaded Methods
4. Dynamic Binding
4.1. Dynamic Binding
4.2. Static Binding
5. Final Keyword
6. Abstract Classes
6.1. Abstract Methods
7. The Object Class
8. Reflection
9. Interfaces
10. Object Cloning
11. Inner Classes
12. Proxies
Inheritance
Inheritance is a process of making a new class that derives from an existing class. The
existing class is called the superclass, base class, or parent class. The new class is called the
subclass, derived class, or child class.
Therefore, a subclass is a specialized version of a superclass. It inherits all of the
instance variables and methods defined by the superclass and add its own, unique elements.
Subclasses of a class can define their own unique behaviors and yet share some of the
same functionality of the parent class.
To inherit a class, you simply incorporate the definition of one class into another by using
the extends keyword. The general form of a class declaration that inherits a superclass is shown
here:
class subclass-name extends superclass-name
{
// body of class
}
You can only specify one superclass for any subclass that you create. Java does not
support the inheritance of multiple superclasses into a single subclass.
Protected features in Java are visible to all subclasses as well as all other classes in the
same package.
Page 24 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Super keyword
Super is a special keyword that directs the compiler to invoke the superclass method.
super has two general forms.
to invoke a superclass constructor.
to invoke a superclass members(variables &methods). invoke a superclass
constructor
CLASS HIERARCHY
The collection of all classes extending from a common superclass is called an inheritance
hierarchy; the path from a particular class to its ancestors in the inheritance hierarchy is its
inheritance chain.
Simple class hierarchies consist of only a superclass and a subclass. But you can build
hierarchies that contain as many layers of inheritance as you like.
Page 25 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
For example, create three classes called A, B, and C, C can be a subclass of B, which is a
subclass of A. When this type of situation occurs, each subclass inherits all of the traits found in
all of its superclasses. In this case, C inherits all aspects of B and A.
POLYMORPHISM
Polymorphism means the ability of methods to behave differently based on the kinds of
input.
Types of polymorphism
Method Overloading
Method overriding
Overloaded methods
Overloaded methods are methods with the same name but different method signature
(either a different number of parameters or different types in the parameter list).
Output
Hai
Hello
Overridden methods
The process of a subclass redefining a method contained in the superclass (with the same
parameter types) is called overriding the method.
Overridden methods allow Java to support run time polymorphism. Whenever a method
is called for a subclass object, the compiler calls the overriding version instead of the superclass
version. The version of the method defined by the superclass will be hidden.
Page 26 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Call to an overridden method is resolved at run time, rather than compile time. Superclass
reference variable can refer to a subclass object. Java uses this fact to resolve calls to overridden
methods at run time. When an overridden method is called through a superclass reference, Java
determines which version of that method to execute based upon the type of the object being
referred to at the time the call occurs. This determination is made at run time.
class Dispatch {
public static void main(String args[]) {
A a = new A(); // object of type A
B b = new B(); // object of type B
C c = new C(); // object of type C
A r; // obtain a reference of type A
r = a; // r refers to an A object
r.callme(); // calls A's version of callme
r = b; // r refers to a B object
r.callme(); // calls B's version of callme
r = c; // r refers to a C object
r.callme(); // calls C's version of callme
}
}
When you override a method, the subclass method must be at least as visible as the
superclass method.
In particular, if the superclass method is public, then the subclass method must also be
declared as public. It is a common error to accidentally omit the public specifier for the subclass
method. Then the compiler complains that you try to supply a weaker access privilege.
Page 27 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Output
Hai
Hello
Methods labeled final, private, or static are not subject to dynamic lookup because they
may not be overridden. private methods are simply not inherited because they would never be
callable anyway. static methods apply to a particular classs static data and thus make no sense in
a derivation. final methods are those designated as not-overridable for reasons of complexity or
safety.
Output
Hai
Hello
DYNAMIC BINDING
Selecting the appropriate method at runtime is called dynamic binding. Dynamic Binding
refers to the case where compiler is not able to resolve the call and the binding is done at runtime
only.
All the instance methods in Java follow dynamic binding.
Page 28 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
1. The compiler looks at the declared type of the object and the method name. The compiler
knows all possible candidates for the method to be called.
2. Next, the compiler determines the types of the parameters that are supplied in the method
call. If among all the methods called fun there is a unique method whose parameter types
are a best match for the supplied parameters, then that method is chosen to be called. This
process is called overloading resolution.
3. If the method is private, static, final, or a constructor, then the compiler knows exactly
which method to call.
4. When the program runs and uses dynamic binding to call a method, then the virtual
machine must call the version of the method that is appropriate for the actual type of the
object. The virtual machine precomputes a method table for each class that lists all
method signatures and the actual methods to be called. When a method is actually called,
the virtual machine simply makes a table lookup. This is used to reduce the time
consumed by searching process.
If the compiler can resolve the binding at the compile time only then such a binding is
called Static Binding or Early Binding. Resolve the call and binding at compile time.
If the method is private, static, final, or a constructor, then the compiler knows exactly
which method to call. This is called static binding.
FINAL KEYWORD
The keyword final has three uses.
Used to create the equivalent of a named constant.
Used to Prevent Overriding
Used to Prevent Inheritance
Named constant
A variable can be declared as final. Doing so prevents its contents from being modified.
This means that you must initialize a final variable when it is declared. For example:
final int constant = 1;
Variables declared as final do not occupy memory on a per-instance basis. Thus, a final variable
is essentially a constant. The keyword final can also be applied to methods, but its meaning is
substantially different than when it is applied to variables. Attempts to change it will generate
either a compile-time error or an exception.
Page 29 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Normally, Java resolves calls to methods dynamically, at run time. This is called late
binding. However, since final methods cannot be overridden, a call to one can be resolved at
compile time. This is called early binding.
ABSTRACT CLASSES
An abstract class is a type of class that is not allowed to be instantiated. The only reason
it exists is to be extended. Abstract classes contain methods and variables common to all the
subclasses, but the abstract class itself is of a type that will not be used directly. Even a single
abstract method requires that a class be marked abstract.
Page 30 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
To declare a class abstract, you simply use the abstract keyword in front of the class
keyword at the beginning of the class declaration.
abstract class classname
{
public abstract type methodname();
// no implementation required
..
}
There can be no objects of an abstract class. That is, an abstract class cannot be directly
instantiated with the new operator. Such objects would be useless, because an abstract class is
not fully defined.
Also, you cannot declare abstract constructors, or abstract static methods. Any subclass
of an abstract class must either implement all of the abstract methods in the superclass, or be
itself declared abstract.
Here is a simple example of a class with an abstract method, followed by a class which
implements that method:
// A Simple demonstration of abstract.
abstract class A
{
abstract void callme();// concrete methods are still allowed in abstract classes
void callmetoo() {
System.out.println("This is a concrete method.");
}
}
class B extends A
{
void callme() {
System.out.println("B's implementation of callme.");
}
}
class AbstractDemo
{
public static void main(String args[]) {
B b = new B();
b.callme();
b.callmetoo();
}
}
That is, sometimes you will want to create a superclass that only defines a generalized
form that will be shared by all of its subclasses, leaving it to each subclass to fill in the details.
Such a class determines the nature of the methods that the subclasses must implement. You can
require that certain methods be overridden by subclasses by specifying the abstract type
Page 31 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
modifier. These methods are sometimes referred to as subclasser responsibility because they
have no implementation specified in the superclass.
Thus, a subclass must override themit cannot simply use the version defined in the
superclass.
Abstract methods
An abstract method is a method declaration that contains no functional code. The reason for
using an abstract method is to ensure that subclasses of this class will include an implementation
of this method. Any concrete class (that is, a class that is not abstract, and therefore capable of
being instantiated) must implement all abstract methods it has inherited.
Methods declared with the keyword abstract define a skeleton for a method but do not
implement it. This requires a derived class to provide the code for this class.
A class with one or more abstract methods must itself be declared abstract and cannot be
instantiated. It can only be used for derivation.
Interfaces
An interface is a collection of method definitions (without implementations) and constant values.
Defining an Interface
This is the general form of an interface:
An interface must be declared with the keyword interface.
Page 32 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Implementation classes must adhere to the same rules for method implementation as a class
extending an abstract class. In order to be a legal implementation class, a nonabstract
implementation class must do the following:
When you implement an interface method, method must be declared as public. (The
access level can be more accessible than that of the overridden method.)
Type signature of the implementing method must match exactly the type signature
specified in the interface definition. (The argument list and return type must exactly
match that of the overridden method.)
A class can implement one or more interfaces.
Partial Implementations: If a class includes an interface but does not fully implement the
methods defined by that interface, then that class must be declared as abstract.
Inner Classes
Inner classes let you make one class a member of another class. Just as classes have
member variables and methods, a class can also have member classes.
You define an inner class within the curly braces of the outer class, as follows:
class MyOuter {
class MyInner { }
}
And if you compile it, %javac MyOuter.java , youll end up with two class files:
MyOuter.class
MyOuter$MyInner.class
The inner class is still, in the end, a separate class, so a class file is generated. But the
inner class file isnt accessible to you in the usual way. The only way you can access the inner
class is through a live instance of the outer class.
Page 33 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
To instantiate an instance of an inner class, you must have an instance of the outer class.
An inner class instance can never stand alone without a direct relationship with a specific
instance of the outer class.
From inside the outer class instance code, use the inner class name in the normal way:
class MyOuter {
private int x = 7;
MyInner mi = new MyInner();
class MyInner {
public void seeOuter() {
System.out.println("Outer x is " + x);
}
}
public static void main(String arg[]){
MyOuter mo=new MyOuter();
mo.mi.seeOuter();
}
}
Output:
Outer x is 7
class MyOuter {
void inner()
{
final int c=9;
class MyInner {
int x=5;
public void display() {
System.out.println("Inner x is " + x);
System.out.println("Inner c is " + c);
}
}
MyInner mi = new MyInner();
mi.display();
}
public static void main(String arg[]){
MyOuter mo = new MyOuter();
mo.inner();
}
}
Page 34 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Output: x is 5
c is 9
An anonymous inner class is always created as part of a statement, so the syntax will end
the class definition with a curly brace, followed by a closing parenthesis to end the
method call, followed by a semicolon to end the statement: });
An anonymous inner class can extend one subclass, or implement one interface. It cannot
both extend a class and implement an interface, nor can it implement more than one
interface.
And if you compile it, %javac Test.java , youll end up with two class files:
A.class
B.class
B$1.class
Test.class
Technically, a static nested class is not an inner class, but instead is considered a top-
level nested class.
Page 35 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Because the nested class is static, it does not share any special relationship with an
instance of the outer class. In fact, you dont need an instance of the outer class to
instantiate a static nested class.
Instantiating a static nested class requires using both the outer and nested class names as
follows:
Output: m=5
The Object class sits at the top of the class hierarchy tree in the Java development
environment. The Object class is the ultimate ancestor
Every class in Java extends Object class.
The Object class defines the basic state and behavior that all objects must have, such as
the ability to compare with another object, to convert to a string, to wait on a condition variable,
to notify other objects that a condition variable has changed, and to return the object's class.
Object defines the following methods, which means that they are available in every
object.
Reflection
Reflection is the ability of the software to analyze itself at runtime.
Reflection is provided by the java.lang.reflect package and elements in class.
This mechanism is helpful to tool builders, not application programmers.
The reflection mechanism is extremely used to
Page 36 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Analyze the capabilities of classes at run time - Examine the structure of class.
Java.lang.Class
Return an array of public fields, methods Return an array of fields, methods and
and constructors that the class supports. This constructors that are declared in the class.
includes all public members of super class. This includes private, protected and public
members of class but not members of super
class.
Java.lang.reflect
Field
import java.lang.reflect.*;
Page 37 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
class Test{
public int var1;
private int var2;
protected int var3;
int var4;
}
public class FieldDemo{
public static void main(String args[])throws Exception{
Class c=Class.forName("Test");
Field f[]=c.getFields();
Field fdec[]=c.getDeclaredFields();
System.out.println("public Fields:");
for(int i=0;i<f.length;i++)
System.out.println(f[i]);
System.out.println("All Fields:");
for(int i=0;i<fdec.length;i++)
System.out.println(fdec[i]);
}
}
Output:
public Fields:
public int Test.var1
All Fields:
public int Test.var1
private int Test.var2
protected int Test.var3
int Test.var4
Method
Provides information about method
The getMethods() method return an array containing Method objects that give you all the
public methods.
The getDeclaredMethods () return all methods of the class or interface. This includes
those inherited from classes or interfaces above it in the inheritance chain.
import java.lang.reflect.*;
class Test{
public void method1()
{}
protected void method2()
{}
private void method3()
{}
void method4()
{}
}
Page 38 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Output:
public Methods of class Test & its Super notifyAll
class: toString
method1 All Methods:
hashCode method1
getClass method2
wait method3
equals method4
notify
Page 39 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Constructor
Provide information about constructors
getConstructors () method return an array containing Constructor objects that give you all
the public constructors
getDeclaredConstructors () method return all constructors of the class represented by the
Class object.
Look at the contents of the data fields. It is easy to look at the contents of a specific field
of an object whose name and type are known when you write a program. But reflection lets you
look at fields of objects that were not known at compile time.
f.set(obj, value) sets the field represented by f of the object obj to the new value.
f.get(obj) returns an object whose value is the current value of the field of obj.
import java.lang.reflect.*;
class A{
public int var1,var2;
A(int i, int j){
var1=i;
var2=j;
}
}
public class ConstructorDemo {
public static void main(String args[]) throws Exception{
A obj=new A(10,20);
System.out.println("Before \n var1= "+obj.var1);
Field f1 = obj.getClass().getField("var1");
int v1 = f1.getInt(obj) + 1;
f1.setInt(obj, v1);
System.out.println("After \n var1= "+v1);
System.out.println("Before \n var2= "+obj.var2);
Field f2 = obj.getClass().getField("var2");
f2.set(obj,21);
System.out.println("After \n var2= "+f2.get(obj));
}
}
Output:
Before var1= 10
After
var1= 11
Before var2= 20
After
Page 40 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
var2= 21
The Array class in the java.lang.reflect package allows you to create arrays dynamically.
First the given array can be converted to an Object[] array. newInstance() method of Array class,
constructs a new array.
Object newarray= Array.newInstance(ComponentType, newlength)
newInstance() method needs two parameters
Component Type of new array
To get component type
1. Get the class object using getClass() method.
2. Confirm that it is really an array using isArray().
3. Use getComponentType method of class Class, to find the right type for the array.
import java.lang.reflect.*;
public class TestArrayRef {
static Object arrayGrow(Object a){
Class cl = a.getClass();
if (!cl.isArray()) return null;
Class componentType = cl.getComponentType();
int length = Array.getLength(a);
int newLength = length + 10;
Object newArray = Array.newInstance(componentType,newLength);
System.arraycopy(a, 0, newArray, 0, length);
return newArray;
}
public static void main(String args[]) throws Exception{
int arr[]=new int[10];
System.out.println(arr.length);
arr = (int[])arrayGrow(arr);
System.out.println(arr.length);
}
}
Output:
10
20
Object cloning
Page 41 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
A clone of an object is a new object that has the same state as the original but a different
identity. You can modify the clone without affecting the original.
When you make a copy of a variable, the original and the copy are references to the same object.
This means a change to either variable also affects the other.
If you want to make a clone of any class then the class must
implement the Cloneable interface, and
Redefine the clone method with the public access modifier.
import java.util.*;
class Test implements Cloneable{
int a=10;
public void display(){
System.out.println("a="+a);
}
public Object clone(){
try{
Test cloned = (Test)super.clone();
return cloned;
}
catch(CloneNotSupportedException e){
return null;
}
}
}
public class CloneDemo{
public static void main(String arg[]){
Test original=new Test();
original.a=20;
Test copy=(Test)original.clone();
copy.a=80;
original.display();
copy.display();
}
}
Output:
a=20
a=80
Proxy
Proxy used to create new classes at runtime that implement a given set of interfaces. The
proxy class can create brand-new classes at runtime.
Page 42 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
The proxy class can create brand-new classes at runtime. Such a proxy class implements
the interfaces that you specify. In particular, the proxy class has the following methods:
All methods required by the specified interfaces;
All methods defined in the Object class (toString, equals, and so on).
To create a proxy object, you use the newProxyInstance method of the Proxy class. The method has
three parameters:
1. A class loader. As part of the Java security model, it is possible to use different
class loaders for system classes, classes that are downloaded from the Internet,
and so on.
2. An array of Class objects, one for each interface to be implemented.
3. An invocation handler.
Page 43 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Frame
Frame is a top-level window that has a title bar, menu bar, borders, and resizing corners. By
default, a frame has a size of 0 0 pixels and it is not visible.
Frames are examples of containers. It can contain other user interface components such as
buttons and text fields.
Container
Window
Frame
Page 44 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
java.awt.Window
void setTitle(String s) - sets the text in the title bar for the frame to the string s.
Frames constructors:
Frame( ) - creates a standard window that does not contain a title.
Frame(String title) - creates a window with the title specified by title
Methods of Frame class:
void setSize(int newWidth, int newHeight) - method is used to set the dimensions of the
window. The dimensions are specified in terms of pixels.
void setVisible(boolean visibleFlag)- The component is visible if the argument to this
method is true. Otherwise, it is hidden.
void setTitle(String newTitle)- change the title in a frame window.
Page 45 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Method :2
Create a subclass of Frame.
In the Subclass constructor
Change the frame title by calling superclass [Frame] constructor using super(String)
method call.
Set the size of the window explicitly by calling the setSize( ) method.
Make the frame visible by calling setVisible() method.
In main() method
Create an instance of subclass.
Example:
The following java program creates a frame with the dimension as 600 x 400 and makes it
visible in the screen. Import java.awt package because Frame class is available in that package.
import java.awt.*; }
public class Demo extends Frame{
Demo(String s){ Out Put:
super(s);
setSize(600,400);
setVisible(true);
}
public static void main(String arg[]){
Demo ob=new Demo("Demo");
Page 46 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
right, and positive y values are down. Coordinate units are measured in pixels (picture element).
All pixel values are integers; there are no partial or fractional pixels.
X coordinate: Horizontal distance moving right from the left of the screen.
Y coordinate: Vertical distance moving from top to bottom of the screen.
The Graphics class provides a set of simple built-in graphics primitives for drawing, including
lines, rectangles, polygons, ovals, and arcs.
Lines
To draw straight lines, use the drawLine method. drawLine takes four arguments: the x and y
coordinates of the starting point and the x and y coordinates of the ending point.
void drawLine(int startX, int startY, int endX, int endY) - displays a line in the current
drawing color that begins at startX,startY and ends at endX,endY.
Example: Demo.java
import java.awt.*; Output:
public class Demo extends Frame{
Demo(String s){
super(s);
setSize(100,100);
setVisible(true);
}
public void paint(Graphics g) {
g.drawLine(10,10,60,60);
}
public static void main(String arg[]){
Demo ob=new Demo("Line Demo");
}
}
Page 47 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Rectangles
The Java graphics primitives provide two kinds of rectangles: Plain rectangles and Rounded
rectangles(which are rectangles with rounded corners).
void drawRect(int x, int y, int width, int height)
void fillRect(int x, int y, int width, int height)
void drawRoundRect(int x, int y, int width, int height, int xDiam, int yDiam)
void fillRoundRect(int x, int y, int width, int height, int xDiam, int yDiam)
A rounded rectangle has rounded corners. The upper-left corner of the rectangle is at x, y. The
dimensions of the rectangle are specified by width and height. The diameter of the rounding arc
along the X axis is specified by xDiam. The diameter of the rounding arc along the Y axis is
specified by yDiam.
Example: Demo.java
import java.awt.*; Demo ob=new Demo("Line Demo");
public class Demo extends Frame{ }
Demo(String s){ }
super(s);
setSize(500,500); Output:
setVisible(true);
}
public void paint(Graphics g) {
g.drawRect(100,100,60,60);
g.fillRect(250,100,60,60);
g.drawRoundRect(100,250,60,60,10,10);
g.fillRoundRect(250,250,60,60,20,20);
}
public static void main(String arg[]){
Page 48 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Polygons
Polygons are shapes with an unlimited number of sides. Set of x and y coordinates are needed to
draw a polygon, and the drawing method starts at one, draws a line to the second, then a line to
the third, and so on.
void drawPolygon(int x[ ], int y[ ], int numPoints)
void fillPolygon(int x[ ], int y[ ], int numPoints)
x[]- An array of integers representing x coordinates
y[]- An array of integers representing y coordinates
numPoints- An integer for the total number of points
Example: Demo.java
import java.awt.*; }
public class Demo extends Frame{ }
public void paint(Graphics g) {
int x1[] = { 39,94,97,112,53,58,26 }; Output:
int y1[] = { 133,174,136,170,208,180,206 };
g.drawPolygon(x1,y1,7);
int x2[] = { 139,194,197,212,153,158,126 };
int y2[] = { 133,174,136,170,208,180,206 };
g.fillPolygon(x2,y2,7);
}
public static void main(String arg[]){
Demo ob=new Demo("Polygon Demo");
Page 49 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Ovals
Use ovals to draw ellipses or circles.
void drawOval(int top, int left, int width, int height)
void fillOval(int top, int left, int width, int height)
Page 50 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Example:Demo.java
import java.awt.*; }
public class Demo extends Frame{ }
Demo(String s){
super(s);
setSize(300,300);
setVisible(true);
}
public void paint(Graphics g) {
g.drawOval(20,120,70,70);
g.fillOval(140,120,100,70);
}
public static void main(String arg[]){
Demo ob=new Demo("Oval Demo");
Arc
The arc is drawn from startAngle through the angular distance specified by arkAngle. Angles are
specified in degrees. The arc is drawn counterclockwise if sweepAngle is positive, and clockwise
if arkAngle is negative.
void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle)
void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle)
x=0
y=0
width=100
height=100
Startangle=90
arcAngle=180
Page 51 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Page 52 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Example:Demo.java
import java.awt.*; }
public class Demo extends Frame{ }
Demo(String s){ Output:
super(s);
setSize(300,300);
setVisible(true);
}
public void paint(Graphics g) {
g.drawArc(20,120,90,90,90,180);
g.fillArc(120,120,90,90,90,180);
g.drawArc(170,120,90,90,90,-180);
}
public static void main(String arg[]){
Demo ob=new Demo("Arc Demo");
Drawing Text
Draw text on the screen using the method drawstring().
void drawstring(String text, int x, int y)- draws a string in the current font and color.
import java.awt.*; }
public class Demo extends Frame{
Demo(String s){
super(s);
setSize(200,200);
setVisible(true);
}
public void paint(Graphics g) {
g.drawString("welcome", 75, 100);
}
public static void main(String arg[]){
Demo ob=new Demo("Text Demo");
}
Page 53 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Page 54 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
java.awt.Component
Component class defines setBackground() and setForeground() methods for setting background
and foreground colors to the window. Since Frame is a subclass of Component class it can use
these methods.
void setBackground(java.awt.Color) set Background color to the window.
void setForeground(java.awt.Color)- set Foreground color to the window.
java.awt.Graphics
setColor() method used to set the current color for the graphics context which is defined in
Graphics class.
void setColor(java.awt.Color)
Page 55 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Example: The following program for designing a frame with square boxes, each of which has a
randomly chosen color in it.
Demo ob=new Demo("Color Demo");
import java.awt.*; }
public class Demo extends Frame{ }
Demo(String s){ Output:
super(s);setSize(200,200);setVisible(true);
setBackground(Color.black);
}
public void paint(Graphics g) {
int rval, gval, bval;
for (int j = 30; j < 200-30; j += 30)
for (int i = 30; i < 200-30; i+= 30){
rval = (int)Math.floor(Math.random() * 256);
gval = (int)Math.floor(Math.random() * 256);
bval = (int)Math.floor(Math.random() * 256);
g.setColor(new Color(rval,gval,bval));
g.fillRect(i,j,25,25);
}
}
public static void main(String arg[]){
Font: java.awt.Font
Font class is used to create Font Objects to set the font for drawing text, labels, textField, buttons
etc..,
One Font constructor has this general form:
Font(String fontName, int fontStyle, int pointSize)
Here, fontName specifies the name of the desired font. The style of the font is specified by
fontStyle. It may consist of one or more of thesethree constants: Font.PLAIN, Font.BOLD, and
Font.ITALIC. The size, in points, of the font is specified by pointSize. point size may or may
not be the height of the characters.
To draw characters in a font, first create an object of the class Font. then specify the font name,
the font style, and the point size.
Page 56 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Methods
Java.awt.Graphics
void setFont(Font fontObj)- selects a font for the graphics context. That font will be used
for subsequent text drawing operations.
Font getFont( )- get the current font by calling getFont( ).
Java.awt.Component
void setFont(Font fontObj)
Example: The following program that draws several lines of text in different fonts.
Page 57 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Java provides the functions for reading images that are stored in local files and display them on
graphics object.
Example: the following program draws a tiled graphics image from the top-left corner to bottom
right corner of the window.
import java.awt.*; }
public class Demo extends Frame{ }
Demo(String s){ Output:
super(s);setSize(300,300);setVisible(true);
}
public void paint(Graphics g) {
Toolkit tk = Toolkit.getDefaultToolkit();
Image img= tk.getImage("E:/Sample/ball.jpg");
for (int i = 20; i <300-20; i=i+20)
for (int j = 40; j <300-20; j=j+20)
g.drawImage(img,i,j,20,20,null);
}
public static void main(String arg[]){
Demo ob=new Demo("Image Demo");
Page 58 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
AWT Components
All components are subclass of Component class
Components allow the user to interact with application. A layout manager
arranges components within a container (Frame/Applet/Panel).
Page 59 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Constructors
Label(String str) - constructs a label with left-aligned text.
Label(String str, int how) - constructs a label with the alignment specified by how.
Methods
void setText(String str)- set the text in the label
String getText( )- return the text of label
Example: The following example creates three labels and adds them to a frame..The labels are
organized in the frame by the flow layout manager.
Page 60 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Page 61 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Button
A push button is a component that contains a label and that generates an event when it is pressed.
Push buttons are objects of type Button.
Constructors
Button( )- creates an empty button
Button(String str)- creates a button that contains str as a label.
Methods
void setLabel(String str) -set the label in the button
String getLabel( ) -return the label of button
Example: The following example creates three buttons and adds them to a frame. The buttons
are organized in the frame by the flow layout manager.
public static void main(String arg[]){
import java.awt.*; Demo ob=new Demo("Button Demo");
public class Demo extends Frame{ }}
FlowLayout flow= new FlowLayout(); Output:
Button b=new Button();
Button b1=new Button();
Button b2=new Button("Button 2");
Demo(String s){
super(s);setSize(200,200);
setLayout(flow);
b1.setLabel("Button 1");
add(b);add(b1);add(b2);
setVisible(true);
}
List
The List class provides a compact, multiple-choice, scrolling selection list. List object can be
constructed to display any number of choices in the visible window. It allows the user to select
multiple items.
Constructors
List( )- allows to select one item at any one time
List(int numRows)- the value of numRows specifies the number of entries in the list that
Page 62 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Page 63 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
CheckBox
A check box is a control that is used to turn an option on or off. It consists of a small box that can
either contain a check mark or not. There is a label associated with each check box that describes
what option the box represents.
Constructors
Checkbox( )- check box whose label is initially blank
Checkbox(String str)- check box whose label is specified by str.
Checkbox(String str, boolean on) - allows you to set the initial state of the check box. If
on is true, the check box is initially checked
Checkbox(String str, boolean on, CheckboxGroup cbGroup)- group is specified by
cbGroup
Checkbox(String str, CheckboxGroup cbGroup, boolean on)
Methods
boolean getState( )
void setState(boolean on)
String getLabel( )
void setLabel(String str)
CheckboxGroup
Create a set of mutually exclusive check boxes in which one and only one check box in the group
can be checked at any one time. These check boxes are often called radio buttons. The default
constructor is defined, which creates an empty group.
Example: The following example creates a checkbox group (Gender) and checkboxes
(Languages Known).
Page 64 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Choice
The Choice class is used to create a pop-up list of items from which the user may choose. It
allows the user to select single item at any time. Choice only defines the default constructor,
which creates an empty list.
To add a item to the list, call add( ). It has this general form:
void add(String name)
To determine which item is currently selected, you may call either getSelectedItem( ) or
getSelectedIndex( ).
Page 65 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
TextField
Text fields allow the user to enter strings and to edit the text using the arrow keys, cut and paste
keys, and mouse selections.
TextField( )- creates a default text field
TextField(int numChars)- creates a text field that is numChars characters wide
TextField(String str)- initializes the text field with the string contained in str
TextField(String str, int numChars)
Methods
String getText( )
void setText(String str)
TextArea
Simple multiline editor allow the user to enter strings.
TextArea and TextField are subclass of TextComponent. Therefore, it supports the getText( ),
setText( ), getSelectedText( ), select( ), isEditable( ), and setEditable( ) methods described in
TextField class.
setVisible(true);
}
public static void main(String arg[]){
Demo ob=new Demo("TextComponents Demo");
}
}
output:
Page 67 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Event handling concept is quite simple: a source generates an event and sends it to one or more
listeners. Listener simply waits until it receives an event. Once received, the listener processes
the event and then returns.
Events
An event is an object that describes a state change in a source. Some of the activities that cause
events to be generated are pressing a button, entering a character via the keyboard, selecting an
item in a list, and clicking the mouse.
Event Sources
A source is an object that generates an event. Sources may generate more than one type of event.
A source must register listeners in order for the listeners to receive notifications about a specific
type of event.
Event Listeners
Listener is an object that is notified when an event occurs. It has two major requirements.
It must have been registered with one or more sources to receive notifications about
specific types of events.
It must implement methods to receive and process these notifications.
The package java.awt.event defines several types of events that are generated by various user
interface elements.
Page 68 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Page 69 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Source: KeyBoard
Event Class: java.awt.event.KeyEvent
Listener Interface: java.awt.event.KeyListener
Example: The following program demonstrates keyboard input. When program receives
keystrokes, identifies the key and perform the corresponding actions specified by the program.
Page 70 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Page 71 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Page 72 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Action Event
To handle Action events, class must implement the ActionListener interface. Source objects
needs to register action listener to receive events.
SourceObject.addActionListener(this);
Source: Button
Event Class: java.awt.event.ActionEvent
Listener Interface: java.awt.event.ActionListener
Example: The following program demonstrates Action event handling. Application window has
3 Text Fields and two buttons. Text fields are used to get user input and show the result to the
user. When the user presses Button, it will generate an action event. Listener receives the event
and performs the operation specified in the actionPerformed Method.
Page 73 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Item Event
To handle Item events, class must implement the ItemListener interface. Source objects needs to
register action listener to receive events.
SourceObject.addActionListener(this);
Source: List, Choice, Checkbox
Event Class: java.awt.event.ItemEvent
Listener Interface: java.awt.event.ItemListener
Example: The following program demonstrates Item event handling. Application window has
Text Field, Checkbox, and Choice. Text fields are used to show the result to the user. When the
user select item from any component, then the selected item will be displayed in text field. A
listener receives the event and performs the operation specified in the itemStateChanged()
Method.
import java.awt.*; TextField t=new TextField(20);
import java.awt.event.*; Demo(String s){
public class Demo extends Frame implements super(s);
ItemListener{ setLayout(flow);
String msg=""; c.add("Chennai");c.add("Coimbatore");
FlowLayout flow=new FlowLayout(); c.add("KanyaKumari");c.add("Madurai");
Label lb1 = new Label("City"); c.add("Tirunelveli");
Label lb2 = new Label("Qualification"); add(lb1);add(c);
Label lb3 = new Label("Languages Known"); add(lb2);add(c1);add(c2);
Choice c=new Choice(); add(lb3);add(c3);add(c4);add(c5);add(c6);
CheckboxGroup cg=new CheckboxGroup(); add(t);
Checkbox c1=new Checkbox("UG",cg,true); setSize(200,300);
Checkbox c2=new Checkbox("PG",cg,false); setVisible(true);
Checkbox c3=new Checkbox("Visual Basic"); c.addItemListener(this);
Checkbox c4=new Checkbox("C++"); c1.addItemListener(this);
Checkbox c5=new Checkbox("Java"); c2.addItemListener(this);
Checkbox c6=new Checkbox("dotnet"); c3.addItemListener(this);
Page 74 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
c4.addItemListener(this);
c5.addItemListener(this);
c6.addItemListener(this);
}
public void itemStateChanged(ItemEvent ie){
String msg=(String)ie.getItem();
t.setText(msg);
}
public static void main(String arg[]){
Demo ob=new Demo("List event Demo");
}
}
Output:
Layout Management
Layout manager automatically arranges several components within a window. Each container
object has a layout manager associated with it.
Panel,Applet - Flow Layout
Frame - Border Layout
Whenever a container is resized, the layout manager is used to position each of the components
within it. General syntax for setting layout to container
Void setLayout(LayouManager obj)
Layout Managers are
FlowLayout
BorderLayout
Grid Layout
GridbagLayout
BoxLayout
Arrange component without using layout Manager:
You can position components manually using setBounds() method defined by
Component class.
1. Disable the default manager of your container.
setLayout(null);
2. Givethe location and size of the component which is to be added in the container.
Page 75 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
The flow layout manager lines the components horizontally until there is no more room and then
starts a new row of components. When the user resizes the container, the layout manager
automatically reflows the components to fill the available space. If you reduce the width of the
frame further, then portions of the wider components begin to disappear. Similarly, if you reduce
the frames vertical size so that theres not enough vertical space to display all rows, some of the
components will become partially or completely inaccessible
import java.awt.*; setVisible(true);
public class Demo extends Frame{ }
FlowLayout flow=new FlowLayout(); public static void main(String arg[]){
Button b1=new Button("one"); Demo ob=new Demo("FlowLayout Demo");
Button b2=new Button("Two"); }
Button b3=new Button("Three"); }
Demo(String s){
super(s);
setLayout(flow);
add(b1);add(b2);add(b3);
setSize(200,200);
Page 76 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
GridLayout
The GridLayout layout manager divides the available space into a grid of cells, evenly allocating
the space among all the cells in the grid and placing one component in each cell.
Cells are always same size. When you resize the window, the cells grow and shrink, but all the
cells have identical sizes.
Constructor
GridLayout(int rows, int cols)- construct a grid with specified rows and cols.
GridLayout(int rows, int cols, int hspace, int vspace) - to specify the amount of horizontal
and vertical space that should appear between adjacent components.
When you create a GridLayout, you can specify a value of 0 for either the row count or the
column count, but not both. If you set the number of rows to 0, GridLayout creates as many rows
as it needs to display all the components using the specified number of columns.
import java.awt.*; Demo ob=new Demo("GridLayout Demo");
public class Demo extends Frame{ }
GridLayout grid=new GridLayout(2,2); }
Button b1=new Button("one");
Button b2=new Button("Two");
Button b3=new Button("Three");
Demo(String s){
super(s);
setLayout(grid);
add(b1);add(b2);add(b3);
setSize(200,200);
setVisible(true);
}
public static void main(String arg[]){
BorderLayout
BorderLayout divides the container into five areas, and you can add a component to each area.
Page 77 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
The five regions correspond to the top, left, bottom, and right sides of the container, along with
one in the center. Each of the five areas is associated with a constant value defined in
BorderLayout: NORTH, SOUTH, EAST, WEST, and CENTER for the top, bottom, right, left,
and center regions, respectively.
Constructor
BorderLayout()
BorderLayout(int hspace, int vspace) leave space between components.
Border layout grows all components to fill the available space.You can add components by
specifying a constraint - BorderLayout.CENTER|NORTH|SOUTH|EAST|WEST
void add(Component obj, constraint)
import java.awt.*;
public class Demo extends Frame{ setVisible(true);
BorderLayout grid=new BorderLayout(); }
Button b1=new Button("one"); public static void main(String arg[]){
Button b2=new Button("Two"); Demo ob=new Demo("BorderLayout Demo");
Button b3=new Button("Three"); }
Button b4=new Button("four"); }
Button b5=new Button("five");
Demo(String s){
super(s);
setLayout(grid);
add(b1,BorderLayout.NORTH);
add(b2,BorderLayout.SOUTH);
add(b3,BorderLayout.CENTER);
add(b4,BorderLayout.EAST);
add(b5,BorderLayout.WEST);
setSize(200,200);
Page 78 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
In Grid bag layout, the rows and columns have variable sizes. It is possible to merge two
adjacent cells and make a space for placing larger components.
To describe the layout to grid bag manager, you must follow the procedure
1. Create an object of type GridBagLayout. No need to specify rows and column.
2. Set this GridBagLayout object to the container.
3. Create an object of type GridBagConstraints. This object will specify how the
components are laid out within the grid bag.
4. For each components, fill in the GridBagConstraints object.Finally add the component
with the constraint by using the call
add(Component, constraint);
GridBagConstraints:
Gridx specify the column position of the component to be added
Gridy - specify the row position of the component to be added
Gridwidth- specify how many columns occupied by the component
Gridheight - specify how many rows occupied by the component
BoxLayout javax.swing
Page 79 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Arrange components in single row or single column. Components are arranged either vertically
from top to bottom or horizontally from left to right
BoxLayout(Container Obj, BoxLayout.X_AXIS | Y_AXIS);
Adapter classes
An adapter class provides an empty implementation of all methods in an event listener interface.
It is useful when you want to receive and process only some of the events that are handled by an
event listener interface.
Define a new class that extends the adapter class and overrides the desired methods only.
Extends adapter class to create Listener and override the desired methods. If you implement the
interface, you have to define all of methods in it. This adapter class defines null methods for all
events, so you can only redefine the methods that you needed.
Some Adapter classes are
KeyAdapter
MouseAdapter
MouseMotionAdapter
Example: If the user only interest in mouse pressed event,then simply extends MouseAdapter
class and redefine the mousePressed event. The following program listening MouseEvent
whenever the user press the mouse it will print mouse pressed text on command prompt.
import java.awt.*; }
import java.awt.event.*; }
public class Demo extends MouseAdapter{
public static void main(String arg[]){
Frame f=new Frame("Mouse Adapter Demo");
f.setSize(200,200);
f.setVisible(true);
Demo ob=new Demo();
f.addMouseListener(ob);
}
public void mousePressed(MouseEvent me){
System.out.println("Mouse pressed..");
Page 80 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Page 81 of 158
Einstein College of Engineering
CS55 PROGRAMMING PARADIGMS
Page 82 of 158
Einstein college of engineering
CS55 PROGRAMMING PARADIGMS
MVC Interaction
In MVC, each of the three elementsthe model, the view, and the controllerrequires
the services of another element to keep itself continually updated.
Page 83 of 158
Einstein college of engineering
CS55 PROGRAMMING PARADIGMS
Introduction to Swing
Swing Features
Pluggable look-and feels -- as above
Lightweight components
o Do not depend on native peers to render themselves.
o Simplified graphics to paint on screen
o Similar behaviour across all platforms
o Portable look and feel
o Only a few top level containers not lightweight.
New components -- tress tables, sliders progress bars, frames, text components.
Tooltips -- textual popup to give additional help
arbitrary keyboard event binding
Debugging support
3 AWT components provide static look Swing components provide dynamic look
and feel. and feel
4 It does not provide Tooltip text for It provide Tooltip text for components
components
Page 84 of 158
Einstein college of engineering
CS55 PROGRAMMING PARADIGMS
Swing Components
javax.swing
Component Constructor Methods
JLabel JLabel() void setText(String str)
JLabel(String text) String getText( )
JLabel(String text, int horizontalAlignment)
JButton JButton( ) void setLabel(String str)
JButton(String str) String getLabel( )
JList JList() Object getSelectedValue( )
JList(String[] ) int getSelectedIndex( )
String[] getSelectedItems( )
JRadioButton JRadioButton()
JRadioButton(String text)
JRadioButton(String text, boolean selected)
JRadioButton(String text, Icon icon, boolean
selected)
JComboBox JComboBox() void add(String name)
JComboBox(Object items[]) String getSelectedItem( )
int getSelectedIndex( )
JCheckbox JCheckbox( ) boolean getState( )
JCheckbox(String str) void setState(boolean on)
JCheckbox(String str, boolean on) String getLabel( )
JCheckBox(String text, Icon icon) void setLabel(String str)
JTextField JTextField(int numChars) String getText( )
JTextField(String str, int numChars) void setText(String str)
void setEditable(boolean
canEdit)
JTextArea JTextArea(int numLines, int numChars) void append(String str)
JTextArea(String str, int numLines, int numChars) void insert(String str, int index)
Page 85 of 158
Einstein college of engineering
CS55 PROGRAMMING PARADIGMS
Swing allows you to create labels that can contain text, images, or both. Unlike
java.awt.Label objects, JLabel objects may consist of both text and graphics (icons).
Text Input
In Java, two components are used to get text input:
JTextField
JTextArea.
The difference between them is that a text field can accept only one line of text and a text
area can accept multiple lines of text. The classes are called JTextField for single-line
input and JTextArea for multiple lines of text.
Page 86 of 158
Einstein college of engineering
CS55 PROGRAMMING PARADIGMS
Page 87 of 158
Einstein college of engineering
CS55 PROGRAMMING PARADIGMS
Unit IV
Generic Programming:
Generics are a facility of generic programming that was added to the Java programming
language.
Generic programming is a style of computer programming in which algorithms are
written in terms of to-be-specified-later types that are then instantiated when needed for
specific types provided as parameters.
Page 88 of 158
Einstein college of engineering
CS55 PROGRAMMING PARADIGMS
System.out.println();
} // end method printArray
System.out.println();
} // end method printArray
System.out.println();
} // end method printArray
Page 89 of 158
Einstein college of engineering
CS55 PROGRAMMING PARADIGMS
} // end main
} // end class OverloadedMethods
Array integerArray contains:
123456
public T getFirst()
{
return first;
}
public S getSecond()
{
return second;
}
private T first;
private S second;
}
This generic class can be used in the following way:
Pair<String, String> grade440 = new Pair<String, String>("mike", "A");
Pair<String, Integer> marks440 = new Pair<String, Integer>("mike",
100);
System.out.println("grade:" + grade440.toString());
System.out.println("marks:" + marks440.toString());
Type erasure
Generics are checked at compile-time for type correctness. The generic type information
is then removed via a process called type erasure. For example, List<Integer> will be
Page 90 of 158
Einstein college of engineering
CS55 PROGRAMMING PARADIGMS
converted to the raw type (non-generic type) List, which can contain arbitrary objects.
However, due to the compile-time check, the resulting code is guaranteed to be type
correct, as long as the code generated no unchecked compiler warnings.
As a result, there is no way to tell at runtime which type parameter is used on an object.
For example, when you examine an ArrayList at runtime, there is no general way to tell
whether it was an ArrayList<Integer> or an ArrayList<Float>. The exception to this
is by using Reflection on existing list elements. However, if the list is empty or if its
elements are subtypes of the parameterized type, even Reflection will not divulge the
parameterized type.
The following code demonstrates that the Class objects appear the same.
ArrayList<Integer> li = new ArrayList<Integer>();
ArrayList<Float> lf = new ArrayList<Float>();
if (li.getClass() == lf.getClass()) // evaluates to true
System.out.println("Equal");
Java generics differ from C++ templates. Java generics generate only one compiled
version of a generic class or function regardless of the number of types used.
Furthermore, the Java compiler does not need to know which parameterized type is used
because the type information is validated at compile-time and erased from the compiled
code. Consequently, one cannot instantiate a Java class of a parameterized type because
instantiation requires a call to a constructor, which is not possible when the type is
unknown at both compile-time and runtime.
T instantiateElementType(List<T> arg)
{
return new T(); //causes a compile error
}
Because there is only one copy of a generic class, static variables are shared among all
the instances of the class, regardless of their type parameter. As a result, the type
parameter cannot be used in the declaration of static variables or in static methods. Static
variables and static methods are "outside" of the scope of the class's parameterized types.
Generic methods:
Generic Methods
Genericity is not limited to classes and interfaces, you can define generic methods. Static
methods, nonstatic methods, and constructors can all be parameterized in almost the same
way as for classes and interfaces, but the syntax is a bit different. Generic methods are
also invoked in the same way as non-generic methods.
Before we see an example of a generics method, consider the following segment of code
that prints out all the elements in a collection:
public void printCollection(Collection c) {
Iterator i = c.iterator();
for(int k = 0;k<c.size();k++) {
System.out.println(i.next());
}
Page 91 of 158
Einstein college of engineering
CS55 PROGRAMMING PARADIGMS
Using generics, this can be re-written as follows. Note that the Collection<?> is the
collection of an unknown type.
void printCollection(Collection<?> c) {
for(Object o:c) {
System.out.println(o);
}
}
Example:
System.out.println();
} // end method printArray
Page 92 of 158
Einstein college of engineering
CS55 PROGRAMMING PARADIGMS
want to accept instances of Number or its subclasses. This is what bounded type
parameters are for.
To declare a bounded type parameter, list the type parameter's name, followed by the
extends keyword, followed by its upper bound, which in this example is Number. Note
that, in this context, extends is used in a general sense to mean either "extends" (as in
classes) or "implements" (as in interfaces).
public class Box<T> {
private T t;
public T get() {
return t;
}
Exceptions:
Exceptions are such anomalous conditions (or typically an event) which
changes the normal flow of execution of a program. Exceptions are used for
signaling erroneous (exceptional) conditions which occur during the run time
processing. Exceptions may occur in any programming language.
Page 93 of 158
Einstein college of engineering
CS55 PROGRAMMING PARADIGMS
Exception Hierarchy:
There are three types of Exceptions:
Page 94 of 158
Einstein college of engineering
CS55 PROGRAMMING PARADIGMS
NoSuchFieldException
InstantiationException
IllegalAccessException
ClassNotFoundException
NoSuchMethodException
CloneNotSupportedException
InterruptedException
Lets take the same file name example as described earlier. In that
example the file name is passed to the constructor for FileReader.
However, the constructor will throwNullPointerException if a logic error
causes a null to be passed to the constructor. Well in this case the
exception could be caught by the application but it would rather try to
eliminate the bug due to which the exception has occurred. You must
have encountered the most common exception in your program i.e.
the ArithmeticException. I am sure you must be familiar with the reason
of its occurrence that is when something tries to divide by zero. Similarly
when an instance data member or method of a reference variable is to
be accessed that hasn't yet referenced an object
throws NullPointerException.
Page 95 of 158
Einstein college of engineering
CS55 PROGRAMMING PARADIGMS
3. Error - The errors in java are external to the application. These are the
exceptional conditions that could not be usually anticipated by the
application and also could not be recovered from. Error exceptions
belong to Error and its subclasses are not subject to the catch or
Specify requirement. Suppose a file is successfully opened by an
application for input but due to some system malfunction could not be
able to read that file then the java.io.IOError would be thrown. This error
will cause the program to terminate but if an application wants then the
error might be caught. An Error indicates serious problems that a
reasonable application should not try to catch. Most such errors are
abnormal conditions.
Hence we conclude that Errors and runtime exceptions are together
called as unchecked exceptions.
Throwing Exceptions
You can throw any type of exception from your code, as long as
your method signature declares it. You can also make up your
own exceptions. Exceptions are regular Java classes that
Page 96 of 158
Einstein college of engineering
CS55 PROGRAMMING PARADIGMS
Catching Exceptions
Page 97 of 158
Einstein college of engineering
CS55 PROGRAMMING PARADIGMS
When the catch block is finished the program continues with any
statements following the catch block. In the example above the
"System.out.println("Division attempt done");" statement will
always get executed.
Propagating Exceptions
Page 98 of 158
Einstein college of engineering
CS55 PROGRAMMING PARADIGMS
int i=0;
while(i != -1){
//reader.read() may throw IOException
i = reader.read();
System.out.println((char) i );
}
reader.close();
System.out.println("--- File End ---");
} catch (FileNotFoundException e) {
//do something clever with the exception
} catch (IOException e) {
//do something clever with the exception
}
}
Page 99 of 158
Einstein college of engineering
CS55 PROGRAMMING PARADIGMS
Finally
} finally {
if(reader != null){
try {
reader.close();
} catch (IOException e) {
//do something clever with the exception
}
}
System.out.println("--- File End ---");
}
You don't need both a catch and a finally block. You can have
one of them or both of them with a try-block, but not none of
them. This code doesn't catch the exception but lets it
propagate up the call stack. Due to the finally block the code still
closes the filer reader even if an exception is thrown.
Logging:
The JDK contains the "Java Logging API". Via a logger you can save text to a
central place to report on errors, provide additional information about your program, etc.
This logging API allows to configure how messages are written by which class with
which priority
The APIs are structured so that calls on the Logger APIs can be
cheap when logging is disabled. If logging is disabled for a given
log level, then the Logger can make a cheap comparison test
and return. If logging is enabled for a given log level, the Logger
is still careful to minimize costs before passing the LogRecord
into the Handlers. In particular, localization and formatting
(which are relatively expensive) are deferred until the Handler
requests them. For example, a MemoryHandler can maintain a
circular buffer of LogRecords without having to pay formatting
costs.
Log Levels
Each log message has an associated log Level. The Level gives
a rough guide to the importance and urgency of a log message.
Log level objects encapsulate an integer value, with higher
values indicating higher priorities.
The Level class defines seven standard log levels, ranging from
FINEST (the lowest priority, with the lowest value) to SEVERE
(the highest priority, with the highest value).
Loggers
Logging level. If a Logger's level is set to be null then the Logger will use an
effective Level that will be obtained by walking up the parent tree and using the
first non-null Level.
Handlers. By default a Logger will log any output messages to its parent's
handlers, and so on recursively up the tree.
Resource bundle names. If a logger has a null resource bundle name, then it will
inherit any resource bundle name defined for its parent, and so on recursively up
the tree.
Logging Methods
First, there are methods that take an explicit source class name
and source method name. These methods are intended for
developers who want to be able to quickly locate the source of
any given logging message. An example of this style is:
Handlers
Formatters
J2SE also includes two standard Formatters:
The LogManager
There is a global LogManager object that keeps track of global logging information. This
includes:
Create a logger
import java.util.logging.Logger;
Level
The log levels define the severity of a message. The class Level
is used to define which messages should be written to the log.
SEVERE (highest)
WARNING
INFO
CONFIG
FINE
FINER
FINEST
In addition to that you have also the levels OFF and ALL to turn
the logging of or to log everything.
For example the following will set the logger to level info which
means all messages with severe, warning and info will be
logged.
LOGGER.setLevel(Level.INFO);
An Example
package logging.example2;
import java.util.logging.Logger;
/**
* A simple Java Hello World program, in the tradition of
* Kernighan and Ritchie.
*/
public class HelloWorld {
private static Logger theLogger =
Logger.getLogger(HelloWorld.class.getName());
import java.util.logging.Logger;
public class HelloWorld {
private static Logger theLogger =
Logger.getLogger(HelloWorld.class.getName());
% java logging.example3.HelloWorld
Hello world
Assertions
An assertion has a Boolean expression that, if evaluated as false,
indicates a bug in the code. This mechanism provides a way to
detect when a program starts falling into an inconsistent state.
Assertions are excellent for documenting assumptions and
invariants about a class. Here is a simple example of assertion:
// ...
// Get a BankAccount object
// ...
}
}
Note: In order for Code Sample 1 to compile, use -source 1.3 because assert is a
keyword as of J2SE 1.4. Otherwise, you will get the following error message:
C:\CLASSES>javac Assertion.java
Assertion.java:11: as of release 1.4, 'assert' is a keyword, and may not be used
as an identifier
(try -source 1.3 or lower to use 'assert' as an identifier)
public static void assert(boolean expression, String why) {
^
1 error
Code Sample 2 demonstrates how to use the Assertion class. In
this example, an integer representing the user's age is read. If
the age is greater than or equal to 18, the assertion evaluates
to true, and it will have no effect on the program execution. But if
the age is less than 18, the assertion evaluates to false. The
program then aborts, displays the message You are too young to vote,
and shows the stack trace.
It is important to note that in this example assertions are used to validate user input and
that no invariant is being tested or verified. This is merely to demonstrate the use of
assertions.
import java.util.Scanner;
import java.io.IOException;
import java.io.IOException;
//Assertion.NDEBUG=false;
switch ((char) c) {
case 's':
case 'S': System.out.println("Single"); break;
case 'm':
case 'M': System.out.println("Married"); break;
case 'd':
case 'D': System.out.println("Divorced"); break;
default: Assertion.assert(!true, "Invalid Option"); break;
}
}
}
Using Assertions
Use the assert statement to insert assertions at particular points in
the code. The assert statement can have one of two forms:
assert booleanExpression;
assert booleanExpression : errorMessage;
The errorMessage is an optional string message that would be
shown when an assertion fails.
}
}
and you enter a valid character, it will work fine. However, if you
enter an invalid character, nothing will happen. This is because,
by default, assertions are disabled at runtime. To enable
assertions, use the switch -enableassertion (or -ea) as follows:
Note: By default, assertions are disabled, so you must not assume that the Boolean
expression contained in an assertion will be evaluated. Therefore, your expressions must
be free of side effects.
The switch -disableassertion (or -da) can be used to disable
assertions. This, however, is most useful when you wish to
disable assertions on classes from specific packages. For
example, to run the program MyClass with assertions disabled in
class Hello, you can use the following command:
Preconditions
In order to retrieve an item from the stack, the stack must not be
empty. The condition that the stack must not be empty is a
precondition. This precondition can be programmed using
assertions as follows:
}
Note: Because assertions might be disabled in some cases, precondition checking can still
be performed by checks inside methods that result in exceptions such
asIllegalArgumentException or NullPointerException.
Postconditions
In order to push an item on the stack, the stack must not be full.
This is a precondition. To add an item on the stack, we assign
the element to be added to the next index in the stack as
follows:
stack[num++] = element;
Class Invariants
UNIT V
Multi Threading:
Java provides built-in support for multithreaded programming. A multithreaded
program contains two or more parts that can run concurrently. Each part of such a
program is called a thread, and each thread defines a separate path of execution.
A multithreading is a specialized form of multitasking. Multitasking threads
require less overhead than multitasking processes.
A process consists of the memory space allocated by the operating system that
can contain one or more threads. A thread cannot exist on its own; it must be a part of a
process. A process remains running until all of the non-daemon threads are done
executing.
Multithreading enables you to write very efficient programs that make maximum
use of the CPU, because idle time can be kept to a minimum.
Life Cycle of a Thread:
A thread goes through various stages in its life cycle. For example, a thread is
born, started, runs, and then dies. Following diagram shows complete life cycle of a
thread.
class ThreadDemo {
public static void main(String args[]) {
new NewThread(); // create a new thread
try {
try {
for(int i = 5; i > 0; i--) {
System.out.println("Child Thread: " + i);
// Let the thread sleep for a while.
Thread.sleep(500);
}
} catch (InterruptedException e) {
System.out.println("Child interrupted.");
}
System.out.println("Exiting child thread.");
}
}
class ExtendThread {
public static void main(String args[]) {
new NewThread(); // create a new thread
try {
for(int i = 5; i > 0; i--) {
System.out.println("Main Thread: " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
}
This would produce following result:
Child thread: Thread[Demo Thread,5,main]
Main Thread: 5
Child Thread: 5
Child Thread: 4
Main Thread: 4
Child Thread: 3
Child Thread: 2
Main Thread: 3
Child Thread: 1
Exiting child thread.
Main Thread: 2
Main Thread: 1
Main thread exiting.
Thread Methods:
Following is the list of important medthods available in the Thread class.
{
Runnable hello = new DisplayMessage("Hello");
Thread thread1 = new Thread(hello);
thread1.setDaemon(true);
thread1.setName("hello");
System.out.println("Starting hello thread...");
thread1.start();
System.out.println("Starting thread3...");
Thread thread3 = new GuessANumber(27);
thread3.start();
try
{
thread3.join();
}catch(InterruptedException e)
{
System.out.println("Thread interrupted.");
}
System.out.println("Starting thread4...");
Thread thread4 = new GuessANumber(75);
thread4.start();
System.out.println("main() is ending...");
}
}
This would produce following result. You can try this example again and again and you
would get different result every time.
Starting hello thread...
Starting goodbye thread...
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Thread-2 guesses 27
Hello
** Correct! Thread-2 in 102 guesses.**
Hello
Starting thread4...
Hello
Hello
..........remaining result produced
Interrupting thrreads:
Interrupting a thread means stopping what it is doing before it has completed its task,
effectively aborting its current operation. Whether the thread dies, waits for new tasks, or
goes on to the next step depends on the application.
Although it may seem simple at first, you must take some precautions in order to achieve
the desired result. There are some caveats you must be aware of as well.
First of all, forget the Thread.stop method. Although it indeed stops a running thread, the
method is unsafe and was deprecated, which means it may not be available in future
versions of the Java.
Another method that can be confusing for the unadvised is Thread.interrupt. Despite what
its name may imply, the method does not interrupt a running thread (more on this later),
as Listing A demonstrates. It creates a thread and tries to stop it usingThread.interrupt.
The calls to Thread.sleep() give plenty of time for the thread initialization and
termination. The thread itself does not do anything useful.
Listing A:
class Example1 extends Thread {
public static void main( String args[] ) throws Exception {
Example1 thread = new Example1();
System.out.println( "Starting thread..." );
thread.start();
Thread.sleep( 3000 );
System.out.println( "Interrupting thread..." );
thread.interrupt();
Thread.sleep( 3000 );
System.out.println( "Stopping application..." );
System.exit( 0 );
}
If you run the code in Listing A, you should see something like this on your console:
Starting thread...
Thread is running...
Thread is running...
Thread is running...
Interrupting thread...
Thread is running...
Thread is running...
Thread is running...
Stopping application...
Even after Thread.interrupt() is called, the thread continues to run for a while.
}
}
Running the code in Listing B will generate output like this (notice how the thread exits
in an orderly fashion):
Starting thread...
Thread is running...
Thread is running...
Thread is running...
Asking thread to stop...
Thread exiting under request...
Stopping application...
Although this method requires some coding, it is not difficult to implement and give the
thread the opportunity to do any cleanup needed, which is an absolute requirement for
any multithreaded application. Just be sure to declare the shared variable as volatile or
enclose any access to it into synchronized blocks/methods.
So far, so good! But what happens if the thread is blocked waiting for some event? Of
course, if the thread is blocked, it can't check the shared variable and can't stop. There are
plenty of situations when that may occur, such as
calling Object.wait(),ServerSocket.accept(), and DatagramSocket.receive(), to name a
few.
They all can block the thread forever. Even if a timeout is employed, it may not be
feasible or desirable to wait until the timeout expires, so a mechanism to prematurely exit
the blocked state must be used.
Unfortunately there is no such mechanism that works for all cases, but the particular
technique to use depends on each situation. In the following sections, I'll give solutions
for the most common cases.
So, if a thread blocks in one of the aforementioned methods, the correct way to stop it is
to set the shared variable and then call the interrupt() method on it (notice that it is
important to set the variable first). If the thread is not blocked, calling interrupt() will not
hurt; otherwise, the thread will get an exception (the thread must be prepared to handle
this condition) and escape the blocked state. In either case, eventually the thread will test
the shared variable and stop. Listing C is a simple example that demonstrates this
technique.
Listing C:
class Example3 extends Thread {
volatile boolean stop = false;
If you're using channels, available with the new I/O API introduced in Java 1.4, the
blocked thread will get a ClosedByInterruptException exception. If that is the case, the
logic is the same as that used in the third exampleonly the exception is different.
But you might be using the traditional I/O available since Java 1.0, since the new I/O is
so recent and requires more work. In this case, Thread.interrupt() doesn't help, since the
thread will not exit the blocked state. Listing D demonstrates that behavior. Although
the interrupt() method is called, the thread does not exit the blocked state.
Listing D:
import java.io.*;
Fortunately, the Java Platform provides a solution for that case by calling
the close()method of the socket the thread is blocked in. In this case, if the thread is
blocked in an I/O operation, the thread will get a SocketException exception, much like
theinterrupt() method causes an InterruptedException to be thrown.
The only caveat is that a reference to the socket must be available so that
its close()method can be called. That means the socket object must also be shared. Listing
Edemonstrates this case. The logic is the same as in the examples presented so far.
And here's the sample output you can expect from running Listing E:
Listing E:
import java.net.*;
import java.io.*;
Starting thread...
Waiting for connection...
Asking thread to stop...
accept() failed or interrupted...
Thread exiting under request...
Stopping application...
Multithreading is a powerful tool, but it presents its own set of challenges. One of these is
how to interrupt a running thread. If properly implemented, these techniques make
interrupting a thread no more difficult than using the built-in operations already provided
by the Java Platform.
Thread Priorities:
Every Java thread has a priority that helps the operating system determine the order in
which threads are scheduled.
Java priorities are in the range between MIN_PRIORITY (a constant of 1) and
MAX_PRIORITY (a constant of 10). By default, every thread is given priority
NORM_PRIORITY (a constant of 5).
Threads with higher priority are more important to a program and should be allocated
processor time before lower-priority threads. However, thread priorities cannot guarantee
the order in which threads execute and very much platform dependentant.
Setting a threads priority can be very useful if one thread has more critical tasks to
perform than another.
The Thread class has a method called setPriority(int level) with which you can alter the
priority a Thread instance has.
The priority level range from 1 (least important) to 10 (most important) and if no level is
explicitly set, a Thread instance has the priority level of 5.
In the first example below no priorites are set, so both threads have the priority level 5.
The TestThread class implements the Runnable interface and in its
run() method loops from 1 to 10 and output the number along with its Thread id, which is
passed to the constructor.
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
System.out.println("Done.");
}
public static void main(String[] args) {
new Main().setPrioritiesOnThreads();
}
int id;
this.id = id;
}
Thread2: 9
Thread2: 10
Thread1: 7
Thread1: 8
Thread1: 9
Thread1: 10
Done.
The output could look different from on execution to another since we have no control of
how the CPU will prioritize them.
If we set the priority on the threads we still haven't got exact control of the execution, but
at least we can tell the CPU which one we think is
most important. The next example is identical to the one above except for the lines where
the priority of the threads are set:
public class Main {
public void setPrioritiesOnThreads() {
thread1.start();
thread2.start();
try {
System.out.println("Done.");
}
public static void main(String[] args) {
new Main().setPrioritiesOnThreads();
}
int id;
this.id = id;
}
Thread 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 synchronization is achieved is called thread synchronization.
The synchronized keyword in Java creates a block of code referred to as a critical section.
Every Java object with a critical section of code gets a lock associated with the object. To
enter a critical section, a thread needs to obtain the corresponding object's lock.
This is the general form of the synchronized statement:
synchronized(object) {
// statements to be synchronized
}
Here, object is a reference to the object being synchronized. A synchronized block
ensures that a call to a method that is a member of object occurs only after the current
thread has successfully entered object's monitor.
Here is an example, using a synchronized block within the run( ) method:
class Callme {
void call(String msg) {
System.out.print("[" + msg);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
System.out.println("]");
}
}
Consider the classic queuing problem, where one thread is producing some data and
another is consuming it. To make the problem more interesting, suppose that the producer
has to wait until the consumer is finished before it generates more data.
In a polling system, the consumer would waste many CPU cycles while it waited for the
producer to produce. Once the producer was finished, it would start polling, wasting more
CPU cycles waiting for the consumer to finish, and so on. Clearly, this situation is
undesirable.
To avoid polling, Java includes an elegant interprocess communication mechanism via
the following methods:
wait( ): This method tells the calling thread to give up the monitor and go to sleep
until some other thread enters the same monitor and calls notify( ).
notify( ): This method wakes up the first thread that called wait( ) on the same
object.
notifyAll( ): This method wakes up all the threads that called wait( ) on the same
object.c The highest priority thread will run first.
These methods are implemented as final methods in Object, so all classes have them. All
three methods can be called only from within a synchronized context.
These methods are declared within Object. Various forms of wait( ) exist that allow you
to specify a period of time to wait.
Example:
The following sample program consists of four classes: Q, the queue that you're trying to
synchronize; Producer, the threaded object that is producing queue entries; Consumer, the
threaded object that is consuming queue entries; and PC, the tiny class that creates the
single Q, Producer, and Consumer.
The proper way to write this program in Java is to use wait( ) and notify( ) to signal in
both directions, as shown here:
class Q {
int n;
boolean valueSet = false;
synchronized int get() {
if(!valueSet)
try {
wait();
} catch(InterruptedException e) {
System.out.println("InterruptedException caught");
}
System.out.println("Got: " + n);
valueSet = false;
notify();
return n;
}
Inside get( ), wait( ) is called. This causes its execution to suspend until the Producer
notifies you that some data is ready.
When this happens, execution inside get( ) resumes. After the data has been obtained,
get( ) calls notify( ). This tells Producer that it is okay to put more data in the queue.
Inside put( ), wait( ) suspends execution until the Consumer has removed the item from
the queue. When execution resumes, the next item of data is put in the queue, and notify(
) is called. This tells the Consumer that it should now remove it.
Here is some output from this program, which shows the clean synchronous behavior:
Put: 1
Got: 1
Put: 2
Got: 2
Put: 3
Got: 3
Put: 4
Got: 4
Put: 5
Got: 5
Thread 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.
For example, suppose one thread enters the monitor on object X and another thread enters
the monitor on object Y. If the thread in X tries to call any synchronized method on Y, it
will block as expected. However, if the thread in Y, in turn, tries to call any synchronized
method on X, the thread waits forever, because to access X, it would have to release its
own lock on Y so that the first thread could complete.
Example:
To understand deadlock fully, it is useful to see it in action. The next example creates two
classes, A and B, with methods foo( ) and bar( ), respectively, which pause briefly before
trying to call a method in the other class.
The main class, named Deadlock, creates an A and a B instance, and then starts a second
thread to set up the deadlock condition. The foo( ) and bar( ) methods use sleep( ) as a
way to force the deadlock condition to occur.
class A {
synchronized void foo(B b) {
String name = Thread.currentThread().getName();
System.out.println(name + " entered A.foo");
try {
Thread.sleep(1000);
} catch(Exception e) {
System.out.println("A Interrupted");
}
System.out.println(name + " trying to call B.last()");
b.last();
}
synchronized void last() {
System.out.println("Inside A.last");
}
}
class B {
synchronized void bar(A a) {
String name = Thread.currentThread().getName();
System.out.println(name + " entered B.bar");
try {
Thread.sleep(1000);
} catch(Exception e) {
System.out.println("B Interrupted");
}
System.out.println(name + " trying to call A.last()");
a.last();
}
synchronized void last() {
System.out.println("Inside A.last");
}
}
class Deadlock implements Runnable {
A a = new A();
B b = new B();
Deadlock() {
Thread.currentThread().setName("MainThread");
Thread t = new Thread(this, "RacingThread");
t.start();
a.foo(b); // get lock on a in this thread.
System.out.println("Back in main thread");
}
public void run() {
b.bar(a); // get lock on b in other thread.
System.out.println("Back in other thread");
}
public static void main(String args[]) {
new Deadlock();
}
}
Here is some output from this program:
MainThread entered A.foo
RacingThread entered B.bar
MainThread trying to call B.last()
RacingThread trying to call A.last()
Because the program has deadlocked, you need to press CTRL-C to end the program.
You can see a full thread and monitor cache dump by pressing CTRL-BREAK on a PC .
You will see that RacingThread owns the monitor on b, while it is waiting for the monitor
on a. At the same time, MainThread owns a and is waiting to get b. This program will
never complete.
As this example illustrates, if your multithreaded program locks up occasionally,
deadlock is one of the first conditions that you should check for.
Thread Control:
While the suspend( ), resume( ), and stop( ) methods defined by Thread class seem to be
a perfectly reasonable and convenient approach to managing the execution of threads,
they must not be used for new Java programs and obsolete in newer versions of Java.
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.
This example is similar to the program in the previous section. However, the deprecated
method calls have been removed. Let us consider the operation of this program.
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.
Example:
// Suspending and resuming a thread for Java 2
class NewThread implements Runnable {
String name; // name of thread
Thread t;
boolean suspendFlag;
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
suspendFlag = false;
t.start(); // Start the thread
}
// This is the entry point for thread.
public void run() {
try {
for(int i = 15; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(200);
synchronized(this) {
while(suspendFlag) {
wait();
}
}
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
System.out.println(name + " exiting.");
}
void mysuspend() {
suspendFlag = true;
}
synchronized void myresume() {
suspendFlag = false;
notify();
}
}
class SuspendResume {
public static void main(String args[]) {
NewThread ob1 = new NewThread("One");
NewThread ob2 = new NewThread("Two");
try {
Thread.sleep(1000);
ob1.mysuspend();
System.out.println("Suspending thread One");
Thread.sleep(1000);
ob1.myresume();
System.out.println("Resuming thread One");
ob2.mysuspend();
System.out.println("Suspending thread Two");
Thread.sleep(1000);
ob2.myresume();
System.out.println("Resuming thread Two");
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
// wait for threads to finish
try {
System.out.println("Waiting for threads to finish.");
ob1.t.join();
ob2.t.join();
} catch (InterruptedException e) {
One exiting.
Main thread exiting.
}
System.out.println("Terminating thread: " + tName );
}
}
class Demo {
public static void main (String args []) {
MyThread thread1 = new MyThread ("1");
MyThread thread2 = new MyThread ("2");
MyThread thread3 = new MyThread ("3");
MyThread thread4 = new MyThread ("4");
System.out.println("Thread Status: Alive");
System.out.println("Thread 1: "
+ thread1.t.isAlive());
System.out.println("Thread 2: "
+ thread2.t.isAlive());
System.out.println("Thread 3: "
+ thread3.t.isAlive());
System.out.println("Thread 4: "
+ thread4.t.isAlive());
try {
System.out.println("Threads Joining.");
thread1.t.join();
thread2.t.join();
thread3.t.join();
thread4.t.join();
} catch (InterruptedException e) {
System.out.println(
"Exception: Thread main interrupted.");
}
System.out.println("Thread Status: Alive");
System.out.println("Thread 1: "
+ thread1.t.isAlive());
System.out.println("Thread 2: "
+ thread2.t.isAlive());
System.out.println("Thread 3: "
+ thread3.t.isAlive());
System.out.println("Thread 4: "
+ thread4.t.isAlive());
System.out.println(
"Terminating thread: main thread.");
}
}
Thread Pools:
Most of the executor implementations in java.util.concurrent use thread pools, which
consist of worker threads. This kind of thread exists separately from the Runnable and
Callable tasks it executes and is often used to execute multiple tasks.
Using worker threads minimizes the overhead due to thread creation. Thread objects use
a significant amount of memory, and in a large-scale application, allocating and
deallocating many thread objects creates a significant memory management overhead.
One common type of thread pool is the fixed thread pool. This type of pool always has a
specified number of threads running; if a thread is somehow terminated while it is still in
use, it is automatically replaced with a new thread. Tasks are submitted to the pool via an
internal queue, which holds extra tasks whenever there are more active tasks than threads.
An important advantage of the fixed thread pool is that applications using it degrade
gracefully. To understand this, consider a web server application where each HTTP
request is handled by a separate thread. If the application simply creates a new thread for
every new HTTP request, and the system receives more requests than it can handle
immediately, the application will suddenly stop responding to all requests when the
overhead of all those threads exceed the capacity of the system. With a limit on the
number of the threads that can be created, the application will not be servicing HTTP
requests as quickly as they come in, but it will be servicing them as quickly as the system
can sustain.
A simple way to create an executor that uses a fixed thread pool is to invoke the
newFixedThreadPool factory method in java.util.concurrent.Executors This class also
provides the following factory methods:
The newCachedThreadPool method creates an executor with an
expandable thread pool. This executor is suitable for applications that
launch many short-lived tasks.
The newSingleThreadExecutor method creates an executor that executes a
single task at a time.
Several factory methods are ScheduledExecutorService versions of the
above executors.
If none of the executors provided by the above factory methods meet your needs,
constructing instances of java.util.concurrent.ThreadPoolExecutor or
java.util.concurrent.ScheduledThreadPoolExecutor will give you additional options.
Callables:
Callables are a tweak to the existing runnable construct. Callables differ only by having a
generic return type - most specialized concurrency APIs already available (such as
Foxtrot ) already have the concept of a runnable + return type (such as the foxtrot Task
and Job classes). Some of you may already have noticed that the ExecutorService API is
biased to Callable objects - and some may consider that a problem since they have a lot
of code that already works with Runnable .
java.util.concurrent
Interface Callable<V>
Type Parameters:
The Executors class contains utility methods to convert from other common forms to
Callable classes.
V call()
Computes a result, or throws an exception if unable to do so.
Example:
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class SimpExec {
public static void main(String args[]) {
CountDownLatch cdl = new CountDownLatch(5);
CountDownLatch cdl2 = new CountDownLatch(5);
CountDownLatch cdl3 = new CountDownLatch(5);
CountDownLatch cdl4 = new CountDownLatch(5);
ExecutorService es = Executors.newFixedThreadPool(2);
try {
cdl.await();
cdl2.await();
cdl3.await();
cdl4.await();
} catch (InterruptedException exc) {
System.out.println(exc);
}
es.shutdown();
}
}
CountDownLatch latch;
MyThread(CountDownLatch c, String n) {
latch = c;
name = n;
new Thread(this);
}
Synchronizers:
Semaphores
A counting semaphore maintains a set of permits. Each acquire() blocks if
necessary until a permit is available, and then takes it. Each release() adds a permit,
potentially releasing a blocking acquirer. However, no actual permit objects are used; the
Semaphore just keeps a count of the number available and acts accordingly.
Semaphores are often used to restrict the number of threads than can access some
(physical or logical) resource.
Example:
import java.util.concurrent.Semaphore;
import java.util.Random;
System.out.println("Busy waiting...");
Barrier
A synchronization aid that allows a set of threads to all wait for each other to
reach a common barrier point. CyclicBarriers are useful in programs involving a fixed
sized group of threads that must occasionally wait for each other. The barrier is called
cyclic because it can be re-used after the waiting threads are released.
}
And an example with two threads.
class BarrierExample
{
Exchangers
A synchronization point at which two threads can exchange objects. Each thread
presents some object on entry to the exchange method, and receives the object presented
by the other thread on return.
Example:
import java.util.concurrent.Exchanger;
class ExgrDemo {
public static void main(String args[]) {
Exchanger<String> exgr = new Exchanger<String>();
new UseString(exgr);
new MakeString(exgr);
}
}
String str;
MakeString(Exchanger<String> c) {
ex = c;
str = new String();
new Thread(this).start();
}
try {
str = ex.exchange(str);
} catch (InterruptedException exc) {
System.out.println(exc);
}
}
}
}
String str;
UseString(Exchanger<String> c) {
ex = c;
new Thread(this).start();
}
invocations of the countDown() method, after which all waiting threads are released and
any subsequent invocations of await return immediately.
Latching variables specify conditions that once set never change. This provides a way to
start several threads and have them wait until a signal is received from a coordinating
thread. [1]
The following program creates a set of threads, but doesn't let any thread start until all the
threads are created.
import java.util.concurrent.*;
CountDownLatch stopLatch;
String name;
Example:
import java.awt.FlowLayout;
import java.lang.reflect.InvocationTargetException;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
try {
print("sleeping for 3 seconds");
Thread.sleep(3000);
}
};
print("about to invokeAndWait()");
SwingUtilities.invokeAndWait(setTextRun);
print("back from invokeAndWait()");
} catch (InterruptedException ix) {
print("interrupted while waiting on invokeAndWait()");
} catch (InvocationTargetException x) {
print("exception thrown from run()");
}
}
}