You are on page 1of 158

EINSTEIN COLLEGE OF ENGINEERING

Sir.C.V.Raman Nagar, Tirunelveli-12

CS55 PROGRAMMING PARADIGMS E - NOTES

Unit No I II III IV V

Title
Object-oriented Programming Fundamentals Object-oriented Programming Inheritance Event-Driven Programming Generic Programming Concurrent Programming

CS55 PROGRAMMING PARADIGMS UNIT I OBJECT-ORIENTED PROGRAMMING FUNDAMENTALS 1) Review of OOP Concepts a) Encapsulation b) Inheritance c) Polymorphism 2) Objects and Classes in Java 3) Language Basics a) Comments b) Data Types c) Variables d) Statements e) Functions 4) Defining Classes 5) Methods 6) Access Specifiers 7) Static Members 8) Constructors a) Parameterized Constructors b) this Keyword c) Garbage Collection 9) Finalize Method 10) Arrays a) One Dimensional Arrays b) Multi Dimensional Arrays 11) Strings 12) Packages 13) JavaDOC Comments 14) References 1. Review OOP concepts The object oriented paradigm is built on the foundation laid by the structured programming concepts. The fundamental change in OOP is that a program is designed around the data being operated upon rather upon the operations themselves. Data and its functions are encapsulated into a single entity. OOP facilitates creating reusable code that can eventually save a lot of work. Polymorphism permits to create multiple definitions for functions. Inheritance permits to derive new classes from old ones. Benefits of object oriented programming Data security is enforced. Inheritance saves time. User defined data types can be easily constructed. Page 2 of 158 Einstein College of Engineering

CS55 PROGRAMMING PARADIGMS Inheritance emphasizes inventions of new data types. Large complexity in the software development can be easily managed.

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

Basic concepts of Object oriented programming All Java programs are object oriented. Computer programs consist of two elements: code and data. In process oriented model code acting on data. Procedural languages such as C employ this model. To manage increasing complexity object-oriented Programming approach was conceived. Object-oriented programming organizes a program around its data (that is, objects) and a set of well-defined interfaces to that data. An object-oriented program can be characterized as data controlling access to code. 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. The Three OOP Principles All object-oriented programming languages provide mechanisms to implement the object-oriented model. They are Encapsulation Inheritance Polymorphism

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

Flying bird
Attributes: --------------------

Non flying bird


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()

Circle Object Draw()

Box Object Draw()

Triangle Object Draw()

2. Class and Object Class defines a new data type. Once defined, this new type can be used to create objects of that type. Thus, a class is a template for an object, and an object is an instance of a class. 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. JAVA Program structure A file containing Java source code is considered a compilation unit. Such a compilation unit contains a set of classes and, optionally, a package definition to group related classes together. Classes contain data and method members that specify the state and behavior of the objects in your program. Java programs come in two flavors: 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: public static void main(String[] args) { ... } 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.
Java Source Code

Java Compiler (Javac)

Java Byte Code (.class)

Java Virtual Machine

Java program Output

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 Java has no global variables. All variables must be declared within either a class scope or a function scope.

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.

The General Form of a Class The class contains data and the code that operates on that data. A class is declared by use of the class keyword. The data, or variables, defined within a class are called instance variables. The code is contained within methods. Collectively, the methods and variables defined within a class are called members of the class. The general form of a class definition is shown here: class classname { type instance-variable1; type instance-variable2; Page 7 of 158 Einstein College of Engineering

CS55 PROGRAMMING PARADIGMS // ... 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. Program includes a method inside the box class. class Box { double width; double height; double depth; // display volume of a box void volume() { System.out.print("Volume is "); System.out.println(width * height * depth); } } 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 default access level When no access specifier is used, then by default the member of a class is public within its own package, but cannot be accessed outside of its package.

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 Object is initialized as specified in the parameters to its constructor. Box mybox1 = new Box(10, 20, 15); The values 10, 20, and 15 are passed to the Box( ) constructor when new creates the object. Thus, mybox1s copy of width, height, and depth will contain the values 10, 20, and 15, respectively. 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 itself regardless of whether or not youve already called it. Finalizer methods are best used for optimizing the removal of an object for 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 Some object-oriented programming languages, notably C++, have explicit destructor methods for any cleanup code that may be needed when an object is no longer used. The most common activity in a destructor is reclaiming the memory set aside for objects. Since Java does automatic garbage collection, manual memory reclamation is not needed, and Java does not support destructors. Of course, some objects utilize a resource other than memory, such as a file or a handle to another object that uses system resources. In this case, it is important that the resource be reclaimed and recycled when it is no longer needed. You can add a finalize method to any class. The finalize method will be called before the garbage collector sweeps away the object. In practice, do not rely on the finalize method for recycling any resources that are in short supplyyou simply cannot know when this method will be called. If a resource needs to be closed as soon as you have finished using it, you need to manage it manually. Add a dispose method that you call to clean up what needs cleaning. Just as importantly, if a class you use has a dispose method, you will want to call it when you are done with the object. In particular, if your class has an instance field that has a dispose method, provide a dispose method that disposes of the instance fields. 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; } Copying Array Elements The library method System.arraycopy() is useful for copying a number of elements from one array to another. The method can be used on any type of array and is declared as follows: 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. char data[] = null; char[] data = null; int length = 60; char[] data = new char [length]; 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 commaseparated 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 twodimensional 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.

There is a second form that may be used to declare an array: type[ ] var-name; Here, the square brackets follow the type specifier, and not the name of the array variable. For example, the following two declarations are equivalent: int al[] = new int[3]; int[] a2 = new int[3]; The following declarations are also equivalent 11. String objects The Java String class (java.lang.String) is a class of object that represents a character array of arbitrary length. While this external class can be used to handle string objects, Java integrates internal, built-in strings into the language.

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. Converting Objects To Strings The String + operator accepts a non-string operand, provided the other operand is a string. The action of the + operator on non-string operands is to convert the non-string to a string, then to do the concatenation. Operands of native types are converted to string by formatting their values. Operands of class types are converted to a string by the method toString() that is defined for all classes. Any object or value can be converted to a string by explicitly using one of the static valueOf() methods defined in class String: String str = String.valueOf (obj); If the argument to valueOf() is of class type, then valueOf() calls that objects toString() method. Any class can define its own toString() method, or just rely on the default. The output produced by toString() is suitable for debugging and diagnostics. It is not meant to be an elaborate text representation of the object, nor is it meant to be parsed. These conversion rules also apply to the right-hand side of the String += operator. Converting Strings To Numbers Methods from the various wrapper classes, such as Integer and Double, can be used to convert numerical strings to numbers. The wrapper classes contain static methods such as parseInt() which convert a string to its own internal data type. 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.*;

Adding a class into a package To place classes inside a package, you must put the name of the package at the top of your source file, before the code that defines the classes in the package. For example, package com.horstmann.corejava; public class Employee 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. 13. Documentation Comments The Java SDK contains a very useful tool, called javadoc, that generates HTML documentation from your source files. If you add comments that start with the special delimiter /** to your source code, you too can produce professional-looking documentation easily. This is a very nice scheme because it lets you keep your code and documentation in one place. If you put your documentation into a separate file, then you probably know that the code and comments tend to diverge over time. But since the documentation comments are in the same file as the source code, it is an easy matter to update both and run javadoc again. How to Insert Comments The javadoc utility extracts information for the following items: Packages Public classes and interfaces Public and protected methods Public and protected fields You can (and should) supply a comment for each of these features. Each comment is placed immediately above the feature it describes. A comment starts with a /** and ends with a */. Each /** . . . */ documentation comment contains free-form text followed by tags. A tag starts with an @, such as @author or @param. The first sentence of the free-form text should be a summary statement. The javadoc utility automatically generates summary pages that extract these sentences. In the free-form text, you can use HTML modifiers such as <em>...</em> for emphasis, <code>...</code> for a monospaced typewriter font, <strong>...</strong> for strong emphasis, and even <img ...> to include an image. You should, however, stay away from heading <h1> or rules <hr> since they can interfere with the formatting of the document.

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 curr ent 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 How to Extract Comments Here, docDirectory is the name of the directory where you want the HTML files to go. Follow these steps: 1. Change to the directory that contains the source files you want to document. If you have nested packages to document, such as com.horstmann.corejava, you must be in the directory that contains the subdirectory com. (This is the directory that contains the overview.html file, if you supplied one.) 2. Run the command javadoc -d docDirectory nameOfPackage for a single package. Or run javadoc -d docDirectory nameOfPackage1 nameOfPackage2... to document multiple packages. If your files are in the default package, then run javadoc -d docDirectory *.java instead. If you omit the -d docDirectory option, then the HTML files are extracted to the current directory. That can get messy, and we don't recommend it. The javadoc program can be fine-tuned by numerous command-line options. For example, you can use the author and -version options to include the @author and @version tags in the documentation. (By default, they are omitted.)

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 UNIT II OBJECT-ORIENTED PROGRAMMING INHERITANCE

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 Member Access and Inheritance 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. 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 Invoke superclass constructor: A subclass can call a constructor method defined by its superclass by use of the following form of super: super(parameter-list); Here, parameter-list specifies any parameters needed by the constructor in the superclass. super( ) must always be the first statement executed inside a subclass constructor. The compiler implicitly calls the base classs no-parameter constructor or default constructor. If the superclass has parameterized constructor and the subclass constructor does not call superclass constructor explicitly, then the Java compiler reports an error. Invoke superclass members: Super always refers to the superclass of the subclass in which it is used. This usage has the following general form: super.member; Here, member can be either a method or an instance variable. This second form of super is most applicable to situations in which member names of a subclass hide members by the same name in the superclass. If a parent class contains a finalize() method, it must be called explicitly by the derived classs finalize() method. super.finalize(); When Constructors are Called Constructors are called in order of derivation, from superclass to subclass. Because a superclass has no knowledge of any subclass, any initialization it needs to perform is separate from and possibly prerequisite to any initialization performed by the subclass. Therefore, it must be executed first. 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). public class Test{ public static void main(String arg[]){ A a=new A(); a.display(); B b=new B(); b.display("Hello"); } } class A{ void display(){ System.out.println("Hai"); } } class B extends A{ void display(String s){ System.out.println(s); } } 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. public class Test1{ public static void main(String arg[]){ A a=new A(); a.display(); B b=new B(); b.display(); } } class A{ protected void display(){ System.out.println("Hai"); } } class B extends A{ public void display(){ System.out.println("Hello"); } } 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 i n a derivation. final methods are those designated as not-overridable for reasons of complexity or safety. public class Test1{ public static void main(String arg[]){ A a1=new A(); a1.display(); A a2=new B(); a2.display(); } } class A{ void display(){ System.out.println("Hai"); } } class B extends A{ void display(){ System.out.println("Hello"); } } 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. Dynamic binding has a very important property: It makes programs extensible without recompiling the existing code. Suppose a new class is added, and there is the possibility that the variable refers to an object of that class. The code contains the method invoking statement of that class need not be recompiled. The method is called automatically if the object happens to refer to the class. Page 28 of 158 Einstein College of Engineering

CS55 PROGRAMMING PARADIGMS

Dynamic Binding or Late Binding It is important to understand what happens when a method call is applied to an object. Here are the details: 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. STATIC BINDING OR EARLY BINDING 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. All the member variables in Java follow static binding. All the static method calls are resolved at compile time itself. All private methods are resolved at compile time itself.

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 Using final to Prevent Overriding Methods declared as final cannot be overridden.The syntax is simple, just put the keyword final after the access specifier and before the return type like this: class A { final void meth() { System.out.println("This is a final method."); } } class B extends A { void meth() { // ERROR! Can't override. System.out.println("Illegal!"); } } 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. Using final to Prevent Inheritance Declaring a class as final implicitly declares all of its methods as final. So it prevents a class from being inherited. To do this, precede the class declaration with final. It is illegal to declare a class as both abstract and final since an abstract class is incomplete by itself and relies upon its subclasses to provide complete implementations. Here is an example of a final class: final class A { // ... } // The following class is illegal. class B extends A { // ERROR! Can't subclass A // ... } 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. To declare an abstract method, use this general form: abstract type name(parameter-list); UAGE But while an abstract class can define both abstract and nonabstract methods, an interface can have only abstract methods. Interface as being similar to an abstract class with no instance fields. 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. access interface name { return-type method-name(parameter-list); type final-varname = value; } It is also possible to declare that an interface is protected so that it can only be implemented by classes in a particular package. However this is very unusual. Rules for interface constants. They must always be public static final Once the value has been assigned, the value can never be modified. The assignment happens in the interface itself (where the constant is declared), so the implementing class can access it and use it, but as a read-only value. To make a class implement an interface, have to carry out two steps: Page 32 of 158 Einstein College of Engineering

CS55 PROGRAMMING PARADIGMS Declare that your class intends to implement the given interface. Supply definitions for all methods in the interface. To declare that a class implements an interface, use the implements keyword: access class classname implements interfacename { //definitions for all methods in the interface } 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 An inner class is a class that is defined inside another class. 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.

Regular Inner Class 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 Instantiating an Inner Class 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. Instantiating an Inner Class from Within Code in 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

Method-Local Inner Classes A method-local inner class is defined within a method of the enclosing class.
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

Anonymous Inner Classes Anonymous inner classes have no name, and their type must be either a subclass of the named type or an implementer of the named interface. 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.
public class Test{ public static void main(String arg[]){ B b=new B(); b.ob.display(); } } class A{ void display(){ System.out.println("Hai"); } } class B { A ob=new A(){ void display(){ System.out.println("Hello"); } }; } Output: Hello

And if you compile it, %javac Test.java , youll end up with two class files: A.class B.class B$1.class Test.class Static Nested Classes Static nested classes are inner classes marked with the static modifier. Technically, a static nested class is not an inner class, but instead is considered a toplevel 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: BigOuter.Nested n = new BigOuter.Nested(); A static nested class cannot access nonstatic members of the outer class, since it does not have an implicit reference to any outer instance (in other words, the nested class instance does not get an outer this reference).
public class Test{ public static void main(String arg[]){ A.B b=new A.B(); b.display(); }} class A { static class B { int m=5; void display(){ System.out.println("m="+m); } } } Output: m=5

The Object Class - The Cosmic Superclass


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 Inspect objects at run time Implement generic array manipulation code Analyze the capabilities of classes at run time - Examine the structure of class.
Java.lang.Class

Field[] getFields() Method[] getMethods() Constructor[] getConstructors()

Field[] getDeclaredFields() Method[] getDeclaredMethods() Constructor[] getDeclaredConstructors()

Return an array of public fields, methods and constructors that the class supports. This includes all public members of super class.

Return an array of fields, methods and constructors that are declared in the class. This includes private, protected and public members of class but not members of super class.

Java.lang.reflect

Field

Method

Constructor

Methods (Field, Method & Constructor): String getName() return the name of the item. int getModifiers()- return an integer, that describes the modifier. Field Provide information about fields. The getFields method returns an array containing Field objects for the public fields. The getDeclaredField method returns an array of Field objects for all fields. The methods return an array of length 0 if there are no such fields.

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


public class MethodDemo{ public static void main(String args[])throws Exception{ Class c=Class.forName("Test"); Method m[]=c.getMethods(); Method mdec[]=c.getDeclaredMethods(); System.out.println("public Methods of class Test & its Super class:"); for(int i=0;i<m.length;i++) System.out.println(m[i].getName()); System.out.println("All Methods:"); for(int i=0;i<mdec.length;i++) System.out.println(mdec[i].getName()); } } Output: public Methods of class Test & its Super class: method1 hashCode getClass wait equals notify notifyAll toString All Methods: method1 method2 method3 method4

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.

Using Reflection to Analyze Objects at Run Time 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

Using Reflection to implement generic array manipulation code 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. Length of new array Length is obtained by getLength() method. It returns the length of any array(method is static method, Array.getLengh(array name)).

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. Proxies can be used for many purposes, such as: Routing method calls to remote servers; Associating user interface events with actions in a running program; Tracing method calls for debugging purposes.

Page 43 of 158 Einstein College of Engineering

CS55 PROGRAMMING PARADIGMS

Unit III Event-Driven Programming Graphics programming

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.

Class hierarchy for Frame Java.awt


Component

Container

Window

Frame

Component & Window class Methods java.awt.Component void setVisible(boolean b) - shows or hides the component depending on whether b is true or false. void setSize(int width, int height) - resizes the component to the specified width and height. void setBounds(int x, int y, int width, int height) - moves and resizes this component. The location of the top-left corner is given by x and y, and the new size is given by the width and height parameters. void setBackground(java.awt.Color) set Background color to the window. void setForeground(java.awt.Color)- set Foreground color to the window. void repaint() - causes a repaint of the component as soon as possible. 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.

Creating a Frame Window Method 1: In main() method Create an instance of a Frame class. Frame f=new Frame(frame name); Set the frame size

f.setSize(500,500); Make the frame visible

f.setVisible(true); 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{ public static void main(String arg[]){ Frame f=new Frame("Demo"); f.setSize(600,400); f.setVisible(true); } } Out Put:

Page 45 of 158 Einstein College of Engineering

CS55 PROGRAMMING PARADIGMS

Method :2 Create a subclass of Frame. In the Subclass constructor 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){ super(s); setSize(600,400); setVisible(true); } public static void main(String arg[]){ Demo ob=new Demo("Demo"); Out Put: }

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.

Working with 2D shapes


Graphics: java.awt.Graphics The Graphics class is part of the java.awt package. The Graphics class defines a number of drawing functions. Each shape can be drawn edge-only or filled. Objects are drawn and filled in the currently selected graphics color, which is black by default. When a graphics object is drawn that exceeds the dimensions of the window, output is automatically clipped. Java Coordinate System Javas coordinate system has the origin (0, 0) in the top left corner. Positive x values are to the 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.*; 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"); } } Output:

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.*; public class Demo extends Frame{ Demo(String s){ super(s); setSize(500,500); 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[]){ Output: } } Demo ob=new Demo("Line Demo");

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 }; 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"); Output: } }

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){ 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"); } } Output:

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

Using color, fonts, and images


Color: java.awt.Color Color class creates a solid RGB color with the specified red, green, blue value in the range (0255). Javas abstract color model uses 24-bit color. The values of each color must be in the range (0- 255). Constructor: Color(int red, int green, int blue) - create new color object for any combination of red, green, and blue. Java.awt.Color class used to create new color object for any combination of red, green, and blue, and it predefines a few color constants. They are stored in class variables,
Color.white (255,255,255) Color.black (0,0,0) Color.lightGray (192,192,192) Color.gray (128,128,128) Color.darkGray (64,64,64) Color.red (255,0,0) Color.green(0,255,0) Color.blue (0,0,255) Color.yellow (255,255,0) Color.magenta (255,0,255) Color.cyan( 0,255,255) Color.pink (255,175,175) Color.orange (255,200,0)

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){ 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[]){ } } Output:

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.
import java.awt.*; public class Demo extends Frame{ Demo(String s){ super(s);setSize(200,200);setVisible(true); } public void paint(Graphics g) { Font f = new Font("TimesRoman", Font.PLAIN, 18); Font fb = new Font("TimesRoman", Font.BOLD, 18); Font fi = new Font("TimesRoman", Font.ITALIC, 18); Font fbi = new Font("TimesRoman", Font.BOLD + Font.ITALIC, 18); g.setFont(f); g.drawString("This is a plain font", 10, 50); g.setFont(fb); g.drawString("This is a bold font", 10, 75); g.setFont(fi); g.drawString("This is an italic font", 10, 100); g.setFont(fbi); g.drawString("This is a bold italic font", 10, 125); } Output: public static void main(String arg[]){ Demo ob=new Demo("Font Demo"); } }

Image: java.awt.Image Image class provides support for displaying and manipulation of graphical images. Image is simply a rectangular graphical object. 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.

Step1: Loading an image java.awt.Toolkit Toolkit getDefaultToolkit()- returns the default toolkit. Image getImage(String filename) - returns an image that will read its pixel data from a file. Toolkit object can only read GIF and JPEG files. Step2: displaying an image java.awt.Graphics boolean drawImage(Image img, int x, int y, ImageObserver observer)- draws a scaled image. boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) draws a scaled image. The system scales the image to fit into a region with the given width and height. Note: This call may return before the image is drawn.

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){ 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"); } } Output:

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).

Adding and Removing Controls add(Component compObj)- add components to the conatainer. Once it is added, it will automatically be visible whenever its parent window is displayed. Here, compObj is an instance of the control that you want to add. void remove(Component obj)- remove a control from a window removeAll( )- remove all controls from a window
Constructor Label( ) Label(String str) Label(String str, int how) Button( ) Button(String str) List( ) List(int numRows) List(int numRows, boolean multipleSelect) Methods void setText(String str) String getText( ) void setLabel(String str) String getLabel( ) void add(String name) void add(String name, int index) String getSelectedItem( ) int getSelectedIndex( ) String[ ] getSelectedItems( ) void add(String name) String getSelectedItem( ) int getSelectedIndex( ) boolean getState( ) void setState(boolean on) String getLabel( ) void setLabel(String str) String getText( ) void setText(String str) void setEditable(boolean canEdit) void append(String str) void insert(String str, int index)

Component Label

Button List

Choice

Choice( )

Checkbox

Checkbox( ) Checkbox(String str) Checkbox(String str, boolean on) Checkbox(String str, boolean on, CheckboxGroup cbGroup) Checkbox(String str, CheckboxGroup cbGroup, boolean on) TextField( ) TextField(int numChars) TextField(String str) TextField(String str, int numChars) TextArea( ) TextArea(int numLines, int numChars) TextArea(String str) TextArea(String str, int numLines, int numChars)

TextField

TextArea

Page 59 of 158 Einstein College of Engineering

CS55 PROGRAMMING PARADIGMS

Scrollbars

Scrollbar( ) Scrollbar(int style) Scrollbar(int style, int initialValue, int thumbSize, int min, int max)

int getMinimum( ) int getMaximum( ) void setValues(int initialValue, int thumbSize, int min, int max)

Label Labels are components that hold text. Labels dont react to user input. It is used to ide ntify components.

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.

import java.awt.*; public class Demo extends Frame{ Label lb1 = new Label("One"); Label lb2 = new Label("Two"); Label lb3 = new Label("Three"); FlowLayout flow= new FlowLayout(); Demo(String s){ super(s); setSize(200,200); setLayout(flow); add(lb1);add(lb2);add(lb3); setVisible(true); } public static void main(String arg[]){ } } Output:

Demo ob=new Demo("Label Demo");

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.*; public class Demo extends Frame{ FlowLayout flow= new FlowLayout(); 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); } }} Output: Demo ob=new Demo("Button Demo");

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

will be visible always List(int numRows, boolean multipleSelect)- if multipleSelect is true, then the user may select two or more items at a time Method void add(String name)- Here, name is the name of the item added to the list. The first form adds items to the end of the list. void add(String name, int index) -adds the item at the index specified by index String getSelectedItem( )- return the selected item String[ ] getSelectedItems( )- return the selected items.

Example: The following example creates a list and adds it to a frame.


import java.awt.*; public class Demo extends Frame{ FlowLayout flow= new FlowLayout(); List l1=new List(2); List l2=new List(3); List l3=new List(4,true); Label lb1 = new Label("Dept"); Label lb2 = new Label("Dept"); Label lb3 = new Label("Dept"); Demo(String s){ super(s); setSize(200,300); setLayout(flow); l1.add("CSE");l1.add("ECE");l1.add("EEE");l1.add("MECH"); l2.add("CSE");l2.add("ECE");l2.add("EEE");l2.add("MECH"); l3.add("CSE");l3.add("ECE");l3.add("EEE");l3.add("MECH"); add(lb1);add(l1);add(lb2);add(l2);add(lb3);add(l3); setVisible(true); } public static void main(String arg[]){ Demo Demo("List Demo"); } } ob=new

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).

import java.awt.*; public class Demo extends Frame{ FlowLayout flow= new FlowLayout(); Label l1=new Label("Gender");

Label l2=new Label("Languages Known"); CheckboxGroup cg=new CheckboxGroup(); Checkbox c1=new Checkbox("Male",cg,true); Checkbox c2=new Checkbox("Female",cg,false);

Page 64 of 158 Einstein College of Engineering

CS55 PROGRAMMING PARADIGMS


Checkbox c3=new Checkbox("VisualBasic"); Checkbox c4=new Checkbox("C++"); Checkbox c5=new Checkbox("Java"); Checkbox c6=new Checkbox("C"); Demo(String s){ super(s); setSize(200,200); setLayout(flow); add(l1);add(c1);add(c2); add(l2);add(c3);add(c4);add(c5);add(c6); setVisible(true); } public static void main(String arg[]){ Demo ob=new Demo("Checkbox Demo"); Output: } }

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( ).
import java.awt.*; public class Demo extends Frame{ FlowLayout flow= new FlowLayout(); Label lb=new Label("City"); Choice c=new Choice(); Demo(String s){ super(s); setSize(200,200);setLayout(flow); c.add("Chennai");c.add("Coimbatore"); c.add("KanyaKumari");c.add("Madurai"); c.add("Tirunelveli"); add(lb);add(c); setVisible(true); } public static void main(String arg[]){ Demo ob=new Demo("Checkbox Demo"); } }

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.

import java.awt.*; public class Demo extends Frame{ FlowLayout flow= new FlowLayout(); Label lb1=new Label("Name"); Label lb2=new Label("No"); Label lb3=new Label("Message"); TextField t1=new TextField(20); TextField t2=new TextField(15);

TextArea ta=new TextArea(2,10); Demo(String s){ super(s); setSize(250,200); setLayout(flow); add(lb1);add(t1); add(lb2);add(t2); add(lb3);add(ta);

Page 66 of 158 Einstein College of Engineering

CS55 PROGRAMMING PARADIGMS


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

Basics of Event Handling 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 Source Button Checkbox Choice List

Description Generates action events when the button is pressed. Generates item events when the check box is selected or deselected. Generates item events when the choice is changed. Generates action events when an item is double-clicked; generates item events when an item is selected or deselected.

Mouse Keyboard

Generates Mouse events when Mouse input occurs. Generates Key events when keyboard input occurs.

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

How event handling in the AWT works A listener object is an instance of a class that implements a special interface called (naturally enough) a listener interface. An event source is an object that can register listener objects and send them event objects. The event source sends out event objects to all registered listeners when that event occurs. The listener objects will then use the information in the event object to determine their reaction to the event. You register the listener object with the source object by using lines of code that follow the model: eventSourceObject.addEventListener(eventListenerObject);

AWT Event Hierarchy java.awt.event

Source Button

Event Class ActionEvent

Class Methods String getActionCommand( )

Listener Interface ActionListener

Interface Methods actionPerformed(ActionEvent ae)

List, Choice, Checkbox Keyboard

ItemEvent

Object getItem( ) ItemSelectable getItemSelectable( )

ItemListener

itemStateChanged(ItemEvent ie)

KeyEvent

char getKeyChar( ) int getKeyCode( )

KeyListener

keyPressed(KeyEvent ke) keyReleased(KeyEvent ke) keyTyped(KeyEvent ke)

Mouse

MouseEvent

int getX( ) int getY( )

MouseListener

mouseClicked(MouseEvent me) mouseEntered(MouseEvent me) mouseExited(MouseEvent me) mousePressed(MouseEvent me) mouseReleased(MouseEvent me)

MouseMotionListener

mouseDragged(MouseEvent me) mouseMoved(MouseEvent me)

Page 69 of 158 Einstein College of Engineering

CS55 PROGRAMMING PARADIGMS

Handling Keyboard Events To handle keyboard events, class must implement the KeyListener interface. Register key listener to receive notifications about KeyEvents. addKeyListener(this);

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.
import java.awt.*; import java.awt.event.*; public class Demo extends Frame implements KeyListener{ int x=20,y=20; Demo(String s){ super(s); setSize(300,300); setVisible(true); addKeyListener(this); } public void keyPressed(KeyEvent ke){ int kc=ke.getKeyCode(); if(kc==37 && x<300) x=x-10; if(kc==39 && x>0) x=x+10; if(kc==38 && y>0) y=y-10; if(kc==40 && y<300) y=y+10; } } Output: } public static void main(String arg[]){ Demo ob=new Demo("Key event Demo"); public void paint(Graphics g){ g.drawRect(x,y,30,30); } public void keyTyped(KeyEvent ke){ } public void keyReleased(KeyEvent ke){ } repaint();

Page 70 of 158 Einstein College of Engineering

CS55 PROGRAMMING PARADIGMS

Handling Mouse Events To handle Mouse events, class must implement the MouseListener & MouseMotionLiatener interface. Register mouse listener & mouse motion listener to receive notifications about MouseEvents. addMouseListener(this); addMouseMotionListener(this); Source: Mouse Event Class: java.awt.event.MouseEvent Listener Interface: java.awt.event.MouseListener java.awt.event.MouseMotionListener Example: The following program demonstrates Mouse event handling. When user drag the mouse it draws a line along the motion path.
import java.awt.*; import java.awt.event.*; public class Demo extends Frame implements MouseListener,MouseMotionListener{ int x1,y1,x2,y2; Demo(String s){ super(s); setSize(300,300); setVisible(true); addMouseListener(this); addMouseMotionListener(this); } public void mouseDragged(MouseEvent me){ x1=x2;y1=y2; x2=me.getX(); y2=me.getY(); Graphics g=this.getGraphics(); g.drawLine(x1,y1,x2,y2); } public void mouseMoved(MouseEvent me){} public void mouseClicked(MouseEvent me){} public void mouseEntered(MouseEvent me){} public void mouseExited(MouseEvent me){ } public void mousePressed(MouseEvent me){ x1=x2=me.getX(); x1=y2=me.getY(); } public void mouseReleased(MouseEvent me){}

Page 71 of 158 Einstein College of Engineering

CS55 PROGRAMMING PARADIGMS


public void paint(Graphics g){} public static void main(String arg[]){ Demo ob=new Demo("Mouse event Demo"); } }

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.
import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Demo extends Frame implements ActionListener{ FlowLayout flow=new FlowLayout(); Label lb1 = new Label("Number1"); Label lb2 = new Label("Number2"); Label lb3 = new Label("Result"); TextField t1=new TextField(20); TextField t2=new TextField(20); TextField t3=new TextField(20); Button b1=new Button("Add"); Button b2=new Button("Multiply"); Demo(String s){ super(s); setLayout(flow); add(lb1);add(t1); add(lb2);add(t2); add(b1);add(b2); add(lb3);add(t3); b1.addActionListener(this); b2.addActionListener(this); setSize(280,280); setVisible(true); } public void actionPerformed(ActionEvent ae){ String s=ae.getActionCommand(); int n1,n2; n1=Integer.parseInt(t1.getText()); n2=Integer.parseInt(t2.getText()); if(s.equals("Add")){ t3.setText(String.valueOf(n1+n2)); } if(s.equals("Multiply")){ t3.setText(String.valueOf(n1*n2)); } } public static void main(String arg[]){ Demo my=new Demo("Action event demo"); } }

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.*; import java.awt.event.*; public class Demo extends Frame implements ItemListener{ String msg=""; FlowLayout flow=new FlowLayout(); Label lb1 = new Label("City"); Label lb2 = new Label("Qualification"); Label lb3 = new Label("Languages Known"); Choice c=new Choice(); CheckboxGroup cg=new CheckboxGroup(); Checkbox c1=new Checkbox("UG",cg,true); Checkbox c2=new Checkbox("PG",cg,false); Checkbox c3=new Checkbox("Visual Basic"); Checkbox c4=new Checkbox("C++"); Checkbox c5=new Checkbox("Java"); Checkbox c6=new Checkbox("dotnet"); TextField t=new TextField(20); Demo(String s){ super(s); setLayout(flow); c.add("Chennai");c.add("Coimbatore"); c.add("KanyaKumari");c.add("Madurai"); c.add("Tirunelveli"); add(lb1);add(c); add(lb2);add(c1);add(c2); add(lb3);add(c3);add(c4);add(c5);add(c6); add(t); setSize(200,300); setVisible(true); c.addItemListener(this); c1.addItemListener(this); c2.addItemListener(this); 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

setBounds(int x, int y, int width, int height); eg: Button b=new Button(click me); b.setBounds(10,10,50,20); FlowLayout FlowLayout arranges the components in rows from left-to-right and top-to-bottom order based on the order in which they were added to the container. FlowLayout arranges components in rows, and the alignment specifies the alignment of the rows. For example, if you create a FlowLayout thats left aligned, the components in each row will appear next to the left edge of the container. The FlowLayout constructors allow you to specify the horizontal and vertical gaps that should appear between components, and if you use a constructor that doesnt accept these values, they both default to 5. Constructor: FlowLayout() - create default layout, which centers component and leaves 5 pixels spaces between each component. FlowLayout(int how)-specify how ech line is aligned.

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.*; public class Demo extends Frame{ FlowLayout flow=new FlowLayout(); Button b1=new Button("one"); 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); setVisible(true); } public static void main(String arg[]){ Demo ob=new Demo("FlowLayout Demo"); } }

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.*; 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[]){ Demo ob=new Demo("GridLayout Demo"); } }

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{ BorderLayout grid=new BorderLayout(); Button b1=new Button("one"); Button b2=new Button("Two"); 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);

setVisible(true); } public static void main(String arg[]){ Demo ob=new Demo("BorderLayout Demo"); } }

GridBag Layout - Gridlayout without limitations 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

import java.awt.*; public class Demo extends Frame{ GridBagLayout gb=new GridBagLayout(); GridBagConstraints gc1= new GridBagConstraints(); GridBagConstraints gc2= new GridBagConstraints(); GridBagConstraints gc3= new GridBagConstraints(); Button b1=new Button("one"); Button b2=new Button("Two"); Button b3=new Button("Three"); Demo(String s){ super(s); setLayout(gb); gc1.gridx=0; gc1.gridy=0; gc1.gridwidth=2; gc1.gridheight=1; gc2.gridx=0; gc2.gridy=1; gc2.gridwidth=1; gc2.gridheight=1; gc3.gridx=1;

gc3.gridy=1; gc3.gridwidth=1; gc3.gridheight=1; add(b1,gc1);add(b2,gc2);add(b3,gc3); setSize(200,200); setVisible(true); } public static void main(String arg[]){ Demo ob=new Demo("GridBagLayout Demo"); }}

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 c ommand 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

Model-View-Controller design pattern


Swing uses the model-view-controller architecture (MVC) as the fundamental design behind each of its components. Essentially, MVC breaks GUI components into three elements. Each of these elements plays a crucial role in how the component behaves.

Model - (includes state data for each component) The model encompasses the state data for each component. There are different models for different types of components. Model has no user interface. Model data always exists independent of the component's visual representation. For example, model of a Choice list might contain the information about list of items and currently selected item. This information remains the same no matter how the component is painted on the screen.

View - (to display component on screen) The view refers to how you see the component on the screen. It determines exactly where and how to draw the choice list by the information offered by the model.

Controller- (handles user Input) The controller decides the behavior of each component with respect to the events. Events come in many forms (a mouse click, a keyboard event).The controller decides how each component will react to the event if it reacts at all.

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 o o o o

Do not depend on native peers to render themselves. Simplified graphics to paint on screen Similar behaviour across all platforms Portable look and feel 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

Difference between AWT and Swing

S.No AWT(Abstract Window Toolkit) 1 AWT components are heavy weight, components are platform dependent. 2

Swing Swing components are light weight,

components are platform independent.

AWT components support Delegate Swing components support MVC (model, Event Model. view, control architecture)

AWT components provide static look Swing components provide dynamic look and feel. and feel It provide Tooltip text for components

It does not provide Tooltip text for components

Page 84 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS

Swing Components javax.swing


Component
JLabel

Constructor
JLabel() JLabel(String text) JLabel(String text, int horizontalAlignment)

Methods
void setText(String str) String getText( )

JButton

JButton( ) JButton(String str)

void setLabel(String str) String getLabel( ) Object getSelectedValue( ) int getSelectedIndex( ) String[] getSelectedItems( )

JList

JList() JList(String[] )

JRadioButton

JRadioButton() JRadioButton(String text) JRadioButton(String text, boolean selected) JRadioButton(String text, Icon icon, boolean selected)

JComboBox

JComboBox() JComboBox(Object items[])

void add(String name) String getSelectedItem( ) int getSelectedIndex( )

JCheckbox

JCheckbox( ) JCheckbox(String str) JCheckbox(String str, boolean on) JCheckBox(String text, Icon icon)

boolean getState( ) void setState(boolean on) String getLabel( ) void setLabel(String str) String getText( ) void setText(String str) void canEdit) setEditable(boolean

JTextField

JTextField(int numChars) JTextField(String str, int numChars)

JTextArea

JTextArea(int numLines, int numChars) JTextArea(String str, int numLines, int numChars)

void append(String str) void insert(String str, int index) void setEchoChar(char echo)

JPasswordField

JPasswordField(String text, int columns)

The JLabel Class 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.

The JPasswordField Class Password fields are a special kind of text field. To avoid nosy bystanders being able to glance at a password, the characters that the user entered are not actually displayed. Instead, each typed character is represented by an echo character, typically an asterisk (*). The Swing set supplies a JPasswordField class that implements such a text field.

The JButton Class They are typically used much like java.awt.Buttons. JButtons fire ActionEvents when they are clicked.

The JCheckBox Class It is used to allow the user to turn a given feature on or off, or to make multiple selections from a set of choices. A JCheckBox is usually rendered by showing a small box into which a "check" is placed when selected. The user could check either, both, or none of the two check boxes. The JRadioButton Class JRadioButtons, allowing users to make a single selection from a set of options.

Page 86 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS The JList Class A list is a graphical component from which the user can select choices. Lists typically display several items at a time, allowing the user to make either a single selection or multiple selections.AWT limited the contents of its List component to strings. The Swing JList component lifts this restriction. List elements can now be strings, images. The JComboBox Class A combo box component is actually a combination of a Swing list and a text field. Unlike lists, a combo box only allows the user one selection at a time, which is usually copied into an editable component at the top, such as a text field. The user can be permitted, however, to manually enter in a selection as well. JComboBox is the Swing version of a combo box component. It is very similar to the AWT Choice component. The JPanel Class JPanel is an extension of JComponent (which, remember, extends java.awt.Container) used for grouping together other components. It gets most of its implementation from its superclasses. Typically, using JPanel amounts to instantiating it, setting a layout manager (this can be set in the constructor and defaults to a FlowLayout), and adding components to it using the add() methods inherited from Container.

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. As per Java Language Specification: A type variable is an unqualified identifier. Type variables are introduced by generic class declarations, generic interface declarations, generic method declarations, and by generic constructor declarations. A class is generic if it declares one or more type variables. These type variables are known as the type parameters of the class. It defines one or more type variables that act as parameters. A generic class declaration defines a set of parameterized types, one for each possible invocation of the type parameter section. All of these parameterized types share the same class at runtime. An interface is generic if it declares one or more type variables. These type variables are known as the type parameters of the interface. It defines one or more type variables that act as parameters. A generic interface declaration defines a set of types, one for each possible invocation of the type parameter section. All parameterized types share the same interface at runtime. A method is generic if it declares one or more type variables. These type variables are known as the formal type parameters of the method. The form of the formal type parameter list is identical to a type parameter list of a class or interface. A constructor can be declared as generic, independently of whether the class the constructor is declared in is itself generic. A constructor is generic if it declares one or more type variables. These type variables are known as the formal type parameters of the constructor. The form of the formal type parameter list is identical to a type parameter list of a generic class or interface.

Motivation for Generics:


Overloaded methods are often used to perform similar operations on different types of data. To motivate generic methods, lets begin with an example that contains three overloaded printArray methods These methods print the string representations of the elements of an Integer array, a Double array and a Character array, respectively. Note that we could have used arrays of primitive types int, double and char in this example. We chose to use arrays of typeInteger, Double and Character to set up our generic method example, because only reference types can be used with generic methods and classes.

Page 88 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS public class OverloadedMethods { // method printArray to print Integer array public static void printArray( Integer[] inputArray ) { // display array elements for ( Integer element : inputArray ) System.out.printf( "%s ", element ); System.out.println(); } // end method printArray // method printArray to print Double array public static void printArray( Double[] inputArray ) { // display array elements for ( Double element : inputArray ) System.out.printf( "%s ", element ); System.out.println(); } // end method printArray // method printArray to print Character array public static void printArray( Character[] inputArray ) { // display array elements for ( Character element : inputArray ) System.out.printf( "%s ", element ); System.out.println(); } // end method printArray public static void main( String args[] ) { // create arrays of Integer, Double and Character Integer[] integerArray = { 1, 2, 3, 4, 5, 6 }; Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7 }; Character[] characterArray = { 'H', 'E', 'L', 'L', 'O' }; System.out.println( "Array integerArray contains:" ); printArray( integerArray ); // pass an Integer array System.out.println( "\nArray doubleArray contains:" ); printArray( doubleArray ); // pass a Double array System.out.println( "\nArray characterArray contains:" ); printArray( characterArray ); // pass a Character array Page 89 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS } // end main } // end class OverloadedMethods Array integerArray contains: 123456 Array doubleArray contains: 1.1 2.2 3.3 4.4 5.5 6.6 7.7 Array characterArray contains: HELLO

Generic class definitions


Here is an example of a generic class:
public class Pair<T, S> { public Pair(T f, S s) { first = f; second = s; } public T getFirst() { return first; } public S getSecond() { return second; } public String toString() { return "(" + first.toString() + ", " + second.toString() + ")"; } 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:
public class GenericMethodTest { // generic method printArray public static < E > void printArray( E[] inputArray ) { // display array elements for ( E element : inputArray ) System.out.printf( "%s ", element ); System.out.println(); } // end method printArray public static void main( String args[] ) { // create arrays of Integer, Double and Character Integer[] intArray = { 1, 2, 3, 4, 5 }; Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7 }; Character[] charArray = { 'H', 'E', 'L', 'L', 'O' }; System.out.println( "Array integerArray contains:" ); printArray( integerArray ); // pass an Integer array System.out.println( "\nArray doubleArray contains:" ); printArray( doubleArray ); // pass a Double array System.out.println( "\nArray characterArray contains:" ); printArray( characterArray ); // pass a Character array } // end main } // end class GenericMethodTest Array integerArray contains: 1 2 3 4 5 6 Array doubleArray contains: 1.1 2.2 3.3 4.4 5.5 6.6 7.7 Array characterArray contains: H E L L O

Bounded Type Parameters: There may be times when you'll want to restrict the kinds of types that are allowed to be passed to a type parameter. For example, a method that operates on numbers might only 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 void add(T t) { this.t = t; } public T get() { return t; } public <U extends Number> void inspect(U u){ System.out.println("T: " + t.getClass().getName()); System.out.println("U: " + u.getClass().getName()); } public static void main(String[] args) { Box<Integer> integerBox = new Box<Integer>(); integerBox.add(new Integer(10)); integerBox.inspect("some text"); // error: String! } }

this

is

still

By modifying our generic method to include this bounded type parameter, compilation will now fail, since our invocation of inspect still includes a String:
Box.java:21: <U>inspect(U) in Box<java.lang.Integer> cannot be applied to (java.lang.String) integerBox.inspect("10"); ^ 1 error

To specify additional interfaces that must be implemented, use the & character, as in:
<U extends Number & MyInterface>

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 Occurrence of any kind of exception in java applications may result in an abrupt termination of the JVM or simply the JVM crashes which leaves the user unaware of the causes of such anomalous conditions. However Java provides mechanisms to handle such situations through its superb exception handling mechanism. The Java programming language uses Exception classes to handle such erroneous conditions and exceptional events. Exception Hierarchy: There are three types of Exceptions:

1. Checked Exceptions - These are the exceptions which occur during the compile time of the program. The compiler checks at the compile time that whether the program contains handlers for checked exceptions or not. These exceptions do not extend RuntimeException class and must be handled to avoid a compile-time error by the programmer. These exceptions extend the java.lang.Exception class These exceptional conditions should be anticipated and recovered by an application. Furthermore Checked exceptions are required to be caught. Remember that all the exceptions are checked exceptions unless and until those indicated by Error, RuntimeException or their subclasses. For example if you call the readLine() method on a BufferedReader object then the IOException may occur or if you want to build a program that could read a file with a specific name then you would be prompted to input a file name by the application. Then it passes the name to the constructor for java.io.FileReader and opens the file. However if you do not provide the name of any existing file then the constructor throwsjava.io.FileNotFoundException which abrupt the application to succeed. Hence this exception will be caught by a well-written application and will also prompt to correct the file name. Here is the list of checked exceptions.

Page 94 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS NoSuchFieldException InstantiationException IllegalAccessException ClassNotFoundException NoSuchMethodException CloneNotSupportedException InterruptedException 2. Unchecked Exceptions - Unchecked exceptions are the exceptions which occur during the runtime of the program. Unchecked exceptions are internal to the application and extend the java.lang.RuntimeException that is inherited from java.lang.Exceptionclass. These exceptions cannot be anticipated and recovered like programming bugs, such as logic errors or improper use of an API. These type of exceptions are also calledRuntime exceptions that are usually caused by data errors, like arithmetic overflow, divide by zero etc. 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. Here is the list of unchecked exceptions. IndexOutOfBoundsException ArrayIndexOutOfBoundsException ClassCastException ArithmeticException NullPointerException IllegalStateException SecurityException 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 If a method needs to be able to throw an exception, it has to declare the exception(s) thrown in the method signature, and then include a throw-statement in the method. Here is an example: public void divide(int numberToDivide, int numberToDivideBy) throws BadNumberException{ if(numberToDivideBy == 0){ throw new BadNumberException("Cannot divide by 0"); } return numberToDivide / numberToDivideBy; }

When an exception is thrown the method stops execution right after the "throw" statement. Any statements following the "throw" statement are not executed. In the example above the "return numberToDivide / numberToDivideBy;" statement is not executed if a BadNumberException is thrown. The program resumes execution when the exception is caught somewhere by a "catch" block. Catching exceptions is explained later. 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 extends java.lang.Exception, or any of the other built-in exception classes. If a method declares that it throws an exception A, then it is also legal to throw subclasses of A. Catching Exceptions If a method calls another method that throws checked exceptions, the calling method is forced to either pass the exception on, or catch it. Catching the exception is done using a try-catch block. Here is an example: public void callDivide(){ try { int result = divide(2,1); System.out.println(result); } catch (BadNumberException e) { //do something clever with the exception System.out.println(e.getMessage()); } System.out.println("Division attempt done"); } The BadNumberException parameter e inside the catch-clause points to the exception thrown from the divide method, if an exception is thrown. If no exeception is thrown by any of the methods called or statements executed inside the try-block, the catch-block is simply ignored. It will not be executed. If an exception is thrown inside the try-block, for instance from the divide method, the program flow of the calling method, callDivide, is interrupted just like the program flow inside divide. The program flow resumes at a catch-block in the call stack that can catch the thrown exception. In the example above the "System.out.println(result);" statement will not get executed if an exception is thrown fromt the divide method. Instead program execution will resume inside the "catch (BadNumberException e) { }" block. If an exception is thrown inside the catch-block and that exception is not caught, the catch-block is interrupted just like the try-block would have been.

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 You don't have to catch exceptions thrown from other methods. If you cannot do anything about the exception where the method throwing it is called, you can just let the method propagate the exception up the call stack to the method that called this method. If you do so the method calling the method that throws the exception must also declare to throw the exception. Here is how the callDivide() method would look in that case. public void callDivide() throws BadNumberException{ int result = divide(2,1); System.out.println(result); } Notice how the try-catch block is gone, and the callDivide method now declares that it can throw a BadNumberException. The program execution is still interrupted if an exception is thrown from the divide method. Thus the "System.out.println(result);" method will not get executed if an exception is thrown from the divide method. But now the program execution is not resumed inside the callDivide method. The exception is propagated to the method that calls callDivide. Program execution doesn't resume until a catch-block somewhere in the call stack catches the exception. All methods in the call stack between the method throwing the exception and the method catching it have their execution stopped at the point in the code where the exception is thrown or propagated. Example: Catching IOException's If an exception is thrown during a sequence of statements inside a try-catch block, the sequence of statements is interrupted and the flow of control will skip directly to the catch-block. This code can be interrupted by exceptions in several places: public void openFile(){ try { // constructor may throw FileNotFoundException FileReader reader = new FileReader("someFile"); 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 } } If the reader.read() method call throws an IOException, the following System.out.println((char) i ); is not executed. Neither is the last reader.close() or the System.out.println("--- File End --"); statements. Instead the program skips directly to the catch(IOException e){ ... } catch clause. If the new FileReader("someFile"); constructor call throws an exception, none of the code inside the try-block is executed. Example: Propagating IOException's This code is a version of the previous method that throws the exceptions instead of catching them: public void openFile() throws IOException { FileReader reader = new FileReader("someFile"); int i=0; while(i != -1){ i = reader.read(); System.out.println((char) i ); } reader.close(); System.out.println("--- File End ---"); } If an exception is thrown from the reader.read() method then program execution is halted, and the exception is passed up the call stack to the method that called openFile(). If the calling method has a try-catch block, the exception will be caught there. If the calling method also just throws the method on, the calling method is also interrupted at the openFile() method call, and the Page 99 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS exception passed on up the call stack. The exception is propagated up the call stack like this until some method catches the exception, or the Java Virtual Machine does. Finally You can attach a finally-clause to a try-catch block. The code inside the finally clause will always be executed, even if an exception is thrown from within the try or catch block. If your code has a return statement inside the try or catch block, the code inside the finally-block will get executed before returning from the method. Here is how a finally clause looks:

public void openFile(){ FileReader reader = null; try { reader = new FileReader("someFile"); int i=0; while(i != -1){ i = reader.read(); System.out.println((char) i ); } } catch (IOException e) { //do something clever with the exception } finally { if(reader != null){ try { reader.close(); } catch (IOException e) { //do something clever with the exception } } System.out.println("--- File End ---"); } } No matter whether an exception is thrown or not inside the try or catch block the code inside the finally-block is executed. The example above shows how the file reader is always closed, regardless of the program flow inside the try or catch block. Note: If an exception is thrown inside a finally block, and it is not caught, then that finally block is interrupted just like the try-block and catch-block is. That is why the previous example had the Page 100 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS reader.close() method call in the finally block wrapped in a trycatch block: } finally { if(reader != null){ try { reader.close(); } catch (IOException e) { //do something clever with the exception } } System.out.println("--- File End ---"); } That way the System.out.println("--- File End ---"); method call will always be executed. If no unchecked exceptions are thrown that is. More about checked and unchecked in a later chapter. 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. public void openFile() throws IOException { FileReader reader = null; try { reader = new FileReader("someFile"); int i=0; while(i != -1){ i = reader.read(); System.out.println((char) i ); } } finally { if(reader != null){ try { reader.close(); } catch (IOException e) { //do something clever with the exception } } System.out.println("--- File End ---"); } }

Page 101 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS Notice how the catch block is gone.

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 Overview of Control Flow Applications make logging calls on Logger objects. Loggers are organized in a hierarchical namespace and child Loggers may inherit some logging properties from their parents in the namespace. Applications make logging calls on Logger objects. These Logger objects allocate LogRecord objects which are passed to Handler objects for publication. Both Loggers and Handlers may use logging Levels and (optionally) Filters to decide if they are interested in a particular LogRecord. When it is necessary to publish a LogRecord externally, a Handler can (optionally) use a Formatter to localize and format the message before publishing it to an I/O stream.

Each Logger keeps track of a set of output Handlers. By default all Loggers also send their output to their parent Logger. But Loggers may also be configured to ignore Handlers higher up the tree. Some Handlers may direct output to other Handlers. For example, the MemoryHandler maintains an internal ring buffer of LogRecords and on trigger events it publishes its LogRecords through a target Handler. In such cases, any formatting is done by the last Handler in the chain. Page 102 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS

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 As stated earlier, client code sends log requests to Logger objects. Each logger keeps track of a log level that it is interested in, and discards log requests that are below this level. Loggers are normally named entities, using dot-separated names such as "java.awt". The namespace is hierarchical and is managed by the LogManager. The namespace should typically be aligned with the Java packaging namespace, but is not required to follow it slavishly. For example, a Logger called "java.awt" might handle logging requests for classes in the java.awt package, but it might also handle logging for classes in

Page 103 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS sun.awt that support the client-visible abstractions defined in the java.awt package. In addition to named Loggers, it is also possible to create anonymous Loggers that don't appear in the shared namespace. See section 1.14. Loggers keep track of their parent loggers in the logging namespace. A logger's parent is its nearest extant ancestor in the logging namespace. The root Logger (named "") has no parent. Anonymous loggers are all given the root logger as their parent. Loggers may inherit various attributes from their parents in the logger namespace. In particular, a logger may inherit:

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 The Logger class provides a large set of convenience methods for generating log messages. For convenience, there are methods for each logging level, named after the logging level name. Thus rather than calling "logger.log(Constants.WARNING,..." a developer can simply call the convenience method "logger.warning(..." There are two different styles of logging methods, to meet the needs of different communities of users. 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:
void warning(String sourceClass, String sourceMethod, String msg);

Second, there are a set of methods that do not take explicit source class or source method names. These are intended for

Page 104 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS developers who want easy-to-use logging and do not require detailed source information.
void warning(String msg);

For this second set of methods, the Logging framework will make a "best effort" to determine which class and method called into the logging framework and will add this information into the LogRecord. However, it is important to realize that this automatically inferred information may only be approximate. The latest generation of virtual machines perform extensive optimizations when JITing and may entirely remove stack frames, making it impossible to reliably locate the calling class and method. Handlers J2SE provides the following Handlers:

StreamHandler: A simple handler for writing formatted records to an OutputStream. ConsoleHandler: A simple handler for writing formatted records to System.err FileHandler: A handler that writes formatted log records either to a single file, or to a set of rotating log files. SocketHandler: A handler that writes formatted log records to remote TCP ports. MemoryHandler: A handler that buffers log records in memory. It is fairly straightforward to develop new Handlers. Developers requiring specific functionality can either develop a Handler from scratch or subclass one of the provided Handlers.

Formatters J2SE also includes two standard Formatters:


SimpleFormatter: Writes brief "human-readable" summaries of log records. XMLFormatter: Writes detailed XML-structured information. As with Handlers, it is fairly straightforward to develop new Formatters.

The LogManager There is a global LogManager object that keeps track of global logging information. This includes:

A hierarchical namespace of named Loggers. Page 105 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS


A set of logging control properties read from the configuration file. There is a single LogManager object that can be retrieved using the static LogManager.getLogManager method. This is created during LogManager initialization, based on a system property. This property allows container applications (such as EJB containers) to substitute their own subclass of LogManager in place of the default class.

Create a logger The package java.util.logging provides the logging capabilities via the class Logger. To create a logger in your Java coding. import java.util.logging.Logger; private final static Logger LOGGER = Logger.getLogger(MyClass.class .getName());

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. Die Log Levels in descending order are:

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);

Page 106 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS An Example To help motivate the use of the logging API, we will use a simple program, based on the idea of a "Hello World" program. public class HelloWorld { public static void main(String[] args) { HelloWorld hello = new HelloWorld("Hello world!"); hello.sayHello(); } private String theMessage; public HelloWorld(String message) { theMessage = message; } public void sayHello() { System.err.println(theMessage); } } We will expand upon this simple program in order to demonstrate and motivate the logging API. The first thing we will do is actually generate a logging message. This is straightforward; we need to create a Logger object, which represents theHelloWorld class, like this: 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()); public static void main(String[] args) { HelloWorld hello = new HelloWorld("Hello world!"); hello.sayHello(); } private String theMessage;

Page 107 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS public HelloWorld(String message) { theMessage = message; } public void sayHello() { System.err.println(theMessage); } } This generates a Logger, which we can use to generate logging messages. Since you typically use one logger per class, we can make it a static field of the HelloWorld class. We use the fully qualified name of the HelloWorld class as the name of theLogger. We'll look at the reasons for this in more detail later. Now, let's actually use the Logger to try to generate a logging message: import java.util.logging.Logger; public class HelloWorld { private static Logger theLogger = Logger.getLogger(HelloWorld.class.getName()); public static void main(String[] args) { HelloWorld hello = new HelloWorld("Hello world!"); hello.sayHello(); } private String theMessage; public HelloWorld(String message) { theMessage = message; } public void sayHello() { theLogger.finest("Hello logging!"); System.err.println(theMessage); } }

The logging API has a configuration file and by default, it provides a handler that will send logging messages, in the form of aLogRecord to the console (System.err). So we would expect to see the string "Hello logging!"; appear before our message of "Hello world!". But if you run this program you only see "Hello world!": Page 108 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS % Hello world What's going on here? The answer lies in the notion of logging levels. 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: BankAccount acct = null; // ... // Get a BankAccount object // ... // Check to ensure we have one assert acct != null; This asserts that acct is not null. If acct is null, an AssertionError is thrown. Any line that executes after the assert statement can safely assume that acct is not null. Using assertions helps developers write code that is more correct, more readable, and easier to maintain. Thus, assertions improve the odds that the behavior of a class matches the expectations of its clients. Note that assertions can be compiled out. In languages such as C/C++, this means using the preprocessor. In C/C++, you can use assertions through the assert macro, which has the following definition in ANSI C:
void assert(int expression)

java

logging.example3.HelloWorld

The program will be aborted if the expression evaluates to false, and it has no effect if the expression evaluates to true. When testing and debugging is completed, assertions do not have to be removed from the program. However, note that the program will be larger in size and therefore slower to load. When assertions are no longer needed, the line
#define NDEBUG

Page 109 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS is inserted at the beginning of the program. This causes the C/C++ preprocessor to ignore all assertions, instead of deleting them manually. In other words, this is a requirement for performance reasons. You should write assertions into software in a form that can be optionally compiled. Thus, assertions should be executed with the code only when you are debugging your program -- that is, when assertions will really help flush out errors. You can think of assertions as a uniform mechanism that replaces the use of ad hoc conditional tests. Implementing Assertions in Java Technology J2SE 1.3 and earlier versions have no built-in support for assertions. They can, however, be provided as an ad hoc solution. Here is an example of how you would roll your own assertion class. Here we have an assert method that checks whether a Boolean expression is true or false. If the expression evaluates to true, then there is no effect. But if it evaluates to false, the assert method prints the stack trace and the program aborts. In this sample implementation, a second argument for a string is used so that the cause of error can be printed. Note that in the assert method, I am checking whether the value of NDEBUG is on (true) or off (false). If NDEBUG sets to true, then the assertion is to be executed. Otherwise, it would have no effect. The user of this class is able to set assertions on or off by toggling the value of NDEBUG. Code Sample 1 shows my implementation. public class Assertion { public static boolean NDEBUG = true; private static void printStack(String why) { Throwable t = new Throwable(why); t.printStackTrace(); System.exit(1); } public static void assert(boolean expression, String why) { if (NDEBUG && !expression) { printStack(why); } Page 110 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS } } 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; public class AssertionTest1 { public static void main(String argv[]) throws IOException { Scanner reader = new Scanner(System.in); System.out.print("Enter your age: "); int age = reader.nextInt(); //Assertion.NDEBUG=false; Assertion.assert(age>=18, "You are too young to vote"); // use age System.out.println("You are eligible to vote"); } } import java.io.IOException; public class AssertionTest2 { public static void main(String argv[]) throws IOException { System.out.print("Enter your marital status: "); int c = System.in.read(); Page 111 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS //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; } } }

In the three examples, if you do not want assertions to be executed as part of the code, uncomment the line
Assert.NDEBUG = false;

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. As an example, I will modify Code Sample 3 to use the assert statement instead of my Assertion class, as shown in Code Sample 4. import java.io.*; public class AssertionTest3 { public static void main(String argv[]) throws IOException { System.out.print("Enter your marital status: "); int c = System.in.read(); switch ((char) c) { case 's': case 'S': System.out.println("Single"); break; case 'm': case 'M': System.out.println("Married"); break; case 'd': Page 112 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS case 'D': System.out.println("Divorced"); break; default: assert !true : "Invalid Option"; break; } } }

prompt> javac

-source

1.4

AssertionTest3.java

If you try to compile your assertion-enabled classes without using the -source 1.4 option, you will get a compiler error saying that assert is a new keyword as of release 1.4. If you now run the program using the command
prompt> java AssertionTest3

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:
prompt> java -ea prompt> java -enableassertion AssertionTest3 AssertionTest3

Following is a sample run: C:\CLASSES>java -ea AssertionTest3 Enter your marital status: w Exception in thread "main" java.lang.AssertionError: Invalid Option at AssertionTest3.main(AssertionTest3.java:15) When an assertion fails, it means that the application has entered an incorrect state. Possible behaviors may include suspending the program or allowing it to continue to run. A good behavior, however, might be to terminate the application, because it may start functioning inappropriately after a failure. In this case, when an assertion fails, an AssertionError is thrown. 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: Page 113 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS


prompt> java -da:com.javacourses.tests.Hello MyClass

And to disable assertions in a specific package and any subpackages it may have, you can use the following command:
prompt> java -da:com.javacourses.tests... MyClass

Note that the three-dot ellipsis (...) is part of the syntax. Switches can be combined. For example, to run a program with assertions enabled in the com.javacourses.tests package (and any subpackages) and disabled in the class com.javacourses.ui.phone, you can use the following command:
prompt> java -ea:com.javacourses.tests... -da:com.javacourses.ui.phone MyClass

Note that when switches are combined and applied to packages, they are applied to all classes, including system classes (which do not have class loaders). But if you use them with no arguments (-ea or -da), they do not apply to system classes. In other words, if you use the command
prompt> java -ea MyClass

then assertions are enabled in all classes except system classes. If you wish to turn assertions on or off in system classes, use the switches -enablesystemassertions (or -esa) and disablesystemassertions (or -dsa). Using Assertions for Design by Contract The assertion facility can help you in supporting an informal design-by-contract style of programming. We will now see examples of using assertions for preconditions, postconditions, and class invariants. The examples are snippets of code from an integer stack, which provides operations such as push to add an item on the stack and pop to retrieve an item from the stack. 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: public int pop() { // precondition assert !isEmpty() : "Stack is empty"; return stack[--num]; Page 114 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS } 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;

However, if you make a mistake and you write this statement as


stack[num] = element

then you have a bug. In this case, we need to ensure that invoking the push operation is working correctly. So the postcondition here is to ensure that the new index in the stack is the old index plus one. Also, we need to make sure that the element has been added on the stack. The following snippet of code shows the push operation with a precondition and a postcondition. public void push(int element) { // precondition assert num<capacity : "stack is full"; int oldNum = num; stack[num] = element; // postcondition assert num == oldNum+1 && stack[num-1] == element : "problem with counter"; } Note that if a method has multiple return statements, then postconditions should be evaluated before each of these return statements. Class Invariants A class invariant is a predicate that must be true before and after any method completes. In the stack example, the invariant would be that the number of elements in the stack is greater than or equal to zero and the number of elements should not exceed the maximum capacity of the class. These conditions, for example, can be coded as follows:

Page 115 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS private boolean inv() { return (num >= 0 && num < capacity); } To check that the stack should satisfy this predicate at all times, each public method and constructor should contain the assertion
assert inv();

right before each return.

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.

Page 116 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS

Above mentioned stages are explained here: New: A new thread begins its life cycle in the new state. It remains in this state until the program starts the thread. It is also referred to as a born thread. Runnable: After a newly born thread is started, the thread becomes runnable. A thread in this state is considered to be executing its task. Waiting: Sometimes a thread transitions to the waiting state while the thread waits for another thread to perform a task.A thread transitions back to the runnable state only when another thread signals the waiting thread to continue executing. Timed waiting: A runnable thread can enter the timed waiting state for a specified interval of time. A thread in this state transitions back to the runnable state when that time interval expires or when the event it is waiting for occurs. Terminated: A runnable thread enters the terminated state when it completes its task or otherwise terminates.

Creating a Thread: Java defines two ways in which this can be accomplished: You can implement the Runnable interface. You can extend the Thread class, itself.

Create Thread by Implementing Runnable: The easiest way to create a thread is to create a class that implements the Runnable interface. To implement Runnable, a class need only implement a single method called run( ), which is declared like this: Page 117 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS public void run( ) You will define the code that constitutes the new thread inside run() method. It is important to understand that run() can call other methods, use other classes, and declare variables, just like the main thread can. After you create a class that implements Runnable, you will instantiate an object of type Thread from within that class. Thread defines several constructors. The one that we will use is shown here: Thread(Runnable threadOb, String threadName); Here threadOb is an instance of a class that implements the Runnable interface and the name of the new thread is specified by threadName. After the new thread is created, it will not start running until you call its start( ) method, which is declared within Thread. The start( ) method is shown here: void start( ); Example: Here is an example that creates a new thread and starts it running: class NewThread implements Runnable { Thread t; NewThread() { // Create a new, second thread t = new Thread(this, "Demo Thread"); System.out.println("Child thread: " + t); t.start(); // Start the thread } public void run() { 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 ThreadDemo { public static void main(String args[]) { new NewThread(); // create a new thread try { Page 118 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS 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. Create Thread by Extending Thread: The second way to create a thread is to create a new class that extends Thread, and then to create an instance of that class. The extending class must override the run( ) method, which is the entry point for the new thread. It must also call start( ) to begin execution of the new thread. Example: Here is the preceding program rewritten to extend Thread: class NewThread extends Thread { NewThread() { // Create a new, second thread super("Demo Thread"); System.out.println("Child thread: " + this); start(); // Start the thread } // This is the entry point for the second thread. public void run() {

Page 119 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS 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. Page 120 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS SN Methods with Description public void start() 1 Starts the thread in a separate path of execution, then invokes the run() method on this Thread object. public void run() 2 If this Thread object was instantiated using a separate Runnable target, the run() method is invoked on that Runnable object. public final void setName(String name) 3 Changes the name of the Thread object. There is also a getName() method for retrieving the name. public final void setPriority(int priority) 4 Sets the priority of this Thread object. The possible values are between 1 and 10. public final void setDaemon(boolean on) 5 A parameter of true denotes this Thread as a daemon thread. public final void join(long millisec) 6 The current thread invokes this method on a second thread, causing the current thread to block until the second thread terminates or the specified number of milliseconds passes. public void interrupt() 7 Interrupts this thread, causing it to continue execution if it was blocked for any reason. public final boolean isAlive() 8 Returns true if the thread is alive, which is any time after the thread has been started but before it runs to completion. The previous methods are invoked on a particular Thread object. The following methods in the Thread class are static. Invoking one of the static methods performs the operation on the currently running thread SN Methods with Description public static void yield() 1 Causes the currently running thread to yield to any other threads of the same priority that are waiting to be scheduled public static void sleep(long millisec) 2 Causes the currently running thread to block for at least the specified number of milliseconds public static boolean holdsLock(Object x) 3 Returns true if the current thread holds the lock on the given Object. public static Thread currentThread() 4 Returns a reference to the currently running thread, which is the thread that invokes this method. public static void dumpStack() 5 Prints the stack trace for the currently running thread, which is useful when debugging a multithreaded application. Example: The following ThreadClassDemo program demonstrates some of these methods of the Thread class: Page 121 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS public class DisplayMessage implements Runnable { private String message; public DisplayMessage(String message) { this.message = message; } public void run() { while(true) { System.out.println(message); } } } // File Name : GuessANumber.java // Create a thread to extentd Thread public class GuessANumber extends Thread { private int number; public GuessANumber(int number) { this.number = number; } public void run() { int counter = 0; int guess = 0; do { guess = (int) (Math.random() * 100 + 1); System.out.println(this.getName() + " guesses " + guess); counter++; }while(guess != number); System.out.println("** Correct! " + this.getName() + " in " + counter + " guesses.**"); } } // File Name : ThreadClassDemo.java public class ThreadClassDemo { public static void main(String [] args) Page 122 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS { Runnable hello = new DisplayMessage("Hello"); Thread thread1 = new Thread(hello); thread1.setDaemon(true); thread1.setName("hello"); System.out.println("Starting hello thread..."); thread1.start(); Runnable bye = new DisplayMessage("Goodbye"); Thread thread2 = new Thread(hello); thread2.setPriority(Thread.MIN_PRIORITY); thread2.setDaemon(true); System.out.println("Starting goodbye thread..."); thread2.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 Page 123 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS 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 ); } public void run() { while ( true ) { System.out.println( "Thread is running..." ); long time = System.currentTimeMillis(); Page 124 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS while ( System.currentTimeMillis()-time < 1000 ) { } } } }

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. Really interrupting a thread The best, recommended way to interrupt a thread is to use a shared variable to signal that it must stop what it is doing. The thread must check the variable periodically, especially during lengthy operations, and terminate its task in an orderly manner.Listing B demonstrates this technique. Listing B:
class Example2 extends Thread { volatile boolean stop = false; public static void main( String args[] ) throws Exception { Example2 thread = new Example2(); System.out.println( "Starting thread..." ); thread.start(); Thread.sleep( 3000 ); System.out.println( "Asking thread to stop..." ); thread.stop = true; Thread.sleep( 3000 ); System.out.println( "Stopping application..." ); System.exit( 0 ); } public void run() { while ( !stop ) { System.out.println( "Thread is running..." ); long time = System.currentTimeMillis(); while ( (System.currentTimeMillis()-time < 1000) && (!stop) ) { } } System.out.println( "Thread exiting under request..." );

Page 125 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS


} }

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. Interrupting a thread with Thread.interrupt() As demonstrated in Listing A, the method Thread.interrupt() does not interrupt a running thread. What the method actually does is to throw an interrupt if the thread is blocked, so that it exits the blocked state. More precisely, if the thread is blocked at one of the methods Object.wait, Thread.join, or Thread.sleep, it receives anInterruptedException, thus terminating the blocking method prematurely. 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 Page 126 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS 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; public static void main( String args[] ) throws Exception { Example3 thread = new Example3(); System.out.println( "Starting thread..." ); thread.start(); Thread.sleep( 3000 ); System.out.println( "Asking thread to stop..." ); thread.stop = true; thread.interrupt(); Thread.sleep( 3000 ); System.out.println( "Stopping application..." ); System.exit( 0 ); } public void run() { while ( !stop ) { System.out.println( "Thread running..." ); try { Thread.sleep( 1000 ); } catch ( InterruptedException e ) { System.out.println( "Thread interrupted..." ); } } System.out.println( "Thread exiting under request..." ); } }

As soon as Thread.interrupt() is called in Listing C, the thread gets an exception so that it escapes the blocked state and determines that it should stop. Running this code produces output like this: Starting thread... Thread running... Thread running... Thread running... Asking thread to stop... Thread interrupted... Thread exiting under request... Stopping application... Interrupting an I/O operation But what happens if the thread is blocked on an I/O operation? I/O can block a thread for a considerable amount of time, particularly if network communication is involved. For example, a server may be waiting for a request, or a network application may be waiting for an answer from a remote host.

Page 127 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS 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 example only 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.*;

class Example4 extends Thread { public static void main( String args[] ) throws Exception { Example4 thread = new Example4(); 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 ); } public void run() { ServerSocket socket; try { socket = new ServerSocket(7856); } catch ( IOException e ) { System.out.println( "Could not create the socket..." ); return; } while ( true ) { System.out.println( "Waiting for connection..." ); try { Socket sock = socket.accept(); } catch ( IOException e ) { System.out.println( "accept() failed or interrupted..." ); } } } }

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.

Page 128 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS 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.*; class Example5 extends Thread { volatile boolean stop = false; volatile ServerSocket socket; public static void main( String args[] ) throws Exception { Example5 thread = new Example5(); System.out.println( "Starting thread..." ); thread.start(); Thread.sleep( 3000 ); System.out.println( "Asking thread to stop..." ); thread.stop = true; thread.socket.close(); Thread.sleep( 3000 ); System.out.println( "Stopping application..." ); System.exit( 0 ); } public void run() { try { socket = new ServerSocket(7856); } catch ( IOException e ) { System.out.println( "Could not create the socket..." ); return; } while ( !stop ) { System.out.println( "Waiting for connection..." ); try { Socket sock = socket.accept(); } catch ( IOException e ) { System.out.println( "accept() failed or interrupted..." ); } } System.out.println( "Thread exiting under request..." ); } }

Starting thread... Waiting for connection... Asking thread to stop... accept() failed or interrupted... Thread exiting under request... Stopping application...

Page 129 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS 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. public class Main { public void setPrioritiesOnThreads() { Thread thread1 = new Thread(new TestThread(1)); Thread thread2 = new Thread(new TestThread(2)); thread1.start(); thread2.start(); try { thread1.join(); thread2.join(); } catch (InterruptedException ex) { ex.printStackTrace(); Page 130 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS } System.out.println("Done.");

} public static void main(String[] args) { new Main().setPrioritiesOnThreads(); }

class TestThread implements Runnable { int id; public TestThread(int id) { this.id = id; } public void run() { for (int i = 1; i <= 10; i++) { System.out.println("Thread" + id + ": " + i); } } } } Since both threads have the same priority, the output will be a mix between them and could look like this: Thread2: 1 Thread1: 1 Thread2: 2 Thread1: 2 Thread2: 3 Thread1: 3 Thread2: 4 Thread1: 4 Thread2: 5 Thread1: 5 Thread2: 6 Thread1: 6 Thread2: 7 Thread2: 8 Page 131 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS 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() { Thread thread1 = new Thread(new TestThread(1)); Thread thread2 = new Thread(new TestThread(2)); //Setting priorities on the Thread objects thread1.setPriority(Thread.MAX_PRIORITY); thread2.setPriority(Thread.MIN_PRIORITY); thread1.start(); thread2.start(); try { //Wait for the threads to finish thread1.join(); thread2.join(); } catch (InterruptedException ex) { ex.printStackTrace(); } System.out.println("Done.");

} public static void main(String[] args) { new Main().setPrioritiesOnThreads(); } Page 132 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS

class TestThread implements Runnable { int id; public TestThread(int id) { this.id = id; } public void run() { for (int i = 1; i <= 10; i++) { System.out.println("Thread" + id + ": " + i); } } } } The output from the code looked like this when executed: Thread1: 1 Thread1: 2 Thread1: 3 Thread1: 4 Thread1: 5 Thread1: 6 Thread1: 7 Thread1: 8 Thread1: 9 Thread1: 10 Thread2: 1 Thread2: 2 Thread2: 3 Thread2: 4 Thread2: 5 Thread2: 6 Thread2: 7 Thread2: 8 Thread2: 9 Thread2: 10 Done. It is however not certain that the first thread will be prioritized to finish before the second thread starts every time. It is up to the CPU to decide.

Page 133 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS 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("]"); } } // File Name : Caller.java class Caller implements Runnable { String msg; Callme target; Thread t; public Caller(Callme targ, String s) { target = targ; msg = s; t = new Thread(this); t.start(); } // synchronize calls to call() public void run() { Page 134 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS synchronized(target) { // synchronized block target.call(msg); } } } // File Name : Synch.java class Synch { public static void main(String args[]) { Callme target = new Callme(); Caller ob1 = new Caller(target, "Hello"); Caller ob2 = new Caller(target, "Synchronized"); Caller ob3 = new Caller(target, "World"); // wait for threads to end try { ob1.t.join(); ob2.t.join(); ob3.t.join(); } catch(InterruptedException e) { System.out.println("Interrupted"); } } } This would produce following result: [Hello] [World] [Synchronized] Interthread Communication: 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. Page 135 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS 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; } synchronized void put(int n) { if(valueSet) try { wait(); } catch(InterruptedException e) { System.out.println("InterruptedException caught"); } this.n = n; valueSet = true; System.out.println("Put: " + n); notify(); } }

Page 136 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS class Producer implements Runnable { Q q; Producer(Q q) { this.q = q; new Thread(this, "Producer").start(); } public void run() { int i = 0; while(true) { q.put(i++); } } } class Consumer implements Runnable { Q q; Consumer(Q q) { this.q = q; new Thread(this, "Consumer").start(); } public void run() { while(true) { q.get(); } } } class PCFixed { public static void main(String args[]) { Q q = new Q(); new Producer(q); new Consumer(q); System.out.println("Press Control-C to stop."); } } 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.

Page 137 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS 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(); Page 138 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS } 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() Page 139 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS 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);

Page 140 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS 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) { Page 141 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS System.out.println("Main thread Interrupted"); } System.out.println("Main thread exiting."); } } Here is the output produced by the above program: New thread: Thread[One,5,main] One: 15 New thread: Thread[Two,5,main] Two: 15 One: 14 Two: 14 One: 13 Two: 13 One: 12 Two: 12 One: 11 Two: 11 Suspending thread One Two: 10 Two: 9 Two: 8 Two: 7 Two: 6 Resuming thread One Suspending thread Two One: 10 One: 9 One: 8 One: 7 One: 6 Resuming thread Two Waiting for threads to finish. Two: 5 One: 5 Two: 4 One: 4 Two: 3 One: 3 Two: 2 One: 2 Two: 1 One: 1 Two exiting. Page 142 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS One exiting. Main thread exiting. Using isAlive() and join(): Typically, the main thread is the last thread to finish in a program. However, there isnt any guarantee that the main thread wont finish before a child thread finishes. In the previous example, we told the main method to sleep until the child threads terminate. However, we estimated the time it takes for the child threads to complete processing. If our estimate was too short, a child thread could terminate after the main thread terminates. Therefore, the sleep technique isnt the best one to use to guarantee that the main thread terminates last. Programmers use two other techniques to ensure that the main thread is the last thread to terminate. These techniques involve calling the isAlive() method and the join() method. Both of these methods are defined in the Thread class. The isAlive() method determines whether a thread is still running. If it is, the isAlive() method returns a Boolean true value; otherwise, a Boolean false is returned. You can use the isAlive() method to examine whether a child thread continues to run. The join() method works differently than the isAlive() method. The join() method waits until the child thread terminates and joins the main thread. In addition, you can use the join() method to specify the amount of time you want to wait for a child thread to terminate. The following example illustrates how to use the isAlive() method and the join() method in your program. This example is nearly the same as the previous example. The difference lies in the main() method of the Demo class definition. After the threads are declared using the constructor of the MyThread class, the isAlive() method is called for each thread. The value returned by the isAlive() method is then displayed on the screen. Next, the join() method is called for each thread. The join() method causes the main thread to wait for all child threads to complete processing before the main thread terminates. class MyThread implements Runnable { String tName; Thread t; MyThread (String threadName) { tName = threadName; t = new Thread (this, tName); t.start(); } public void run() { try { System.out.println("Thread: " + tName ); Thread.sleep(2000); } catch (InterruptedException e ) { System.out.println("Exception: Thread " + tName + " interrupted"); Page 143 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS } 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."); } }

Page 144 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS Here is what is displayed on the screen when this program runs: Thread Status: Alive Thread 1: true Thread 2: true Thread 3: true Thread 4: true Threads Joining. Thread: 1 Thread: 2 Thread: 3 Thread: 4 Terminating thread: 1 Terminating thread: 2 Terminating thread: 3 Terminating thread: 4 Thread Status: Alive Thread 1: false Thread 2: false Thread 3: false Thread 4: false 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.

Page 145 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS 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 . public class ComplexCalculation implements Callable<Long> { public ComplexCalculation(int value1, int value2, long value3) { // ... } public Long call() { // perform complex calculation resulting in long long result = //... return result; // autoboxing! } } java.util.concurrent Interface Callable<V> Type Parameters: V - the result type of method call

Page 146 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS public interface Callable<V> A task that returns a result and may throw an exception. Implementors define a single method with no arguments called call. The Callable interface is similar to Runnable, in that both are designed for classes whose instances are potentially executed by another thread. A Runnable, however, does not return a result and cannot throw a checked exception. Executors: There's a close connection between the task being done by a new thread, as defined by its Runnable object, and the thread itself, as defined by a Thread object. This works well for small applications, but in large-scale applications, it makes sense to separate thread management and creation from the rest of the application. Objects that encapsulate these functions are known as executors. 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); es.execute(new MyThread(cdl, "A")); es.execute(new MyThread(cdl2, "B")); es.execute(new MyThread(cdl3, "C")); es.execute(new MyThread(cdl4, "D")); try { cdl.await(); cdl2.await(); cdl3.await(); Page 147 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS cdl4.await(); } catch (InterruptedException exc) { System.out.println(exc); } es.shutdown(); } } class MyThread implements Runnable { String name; CountDownLatch latch; MyThread(CountDownLatch c, String n) { latch = c; name = n; new Thread(this); } public void run() { for (int i = 0; i < 5; i++) { latch.countDown(); } } } Synchronizers: Java 5 introduces general purpose synchronizer classes, including semaphores, mutexes, barriers, latches, and exchangers, which facilitate coordination between threads. These classes are a apart of the java.util.concurrent package. A brief description of each of these follows: 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.

Page 148 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS 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; //Solving the mutual exclusion problem using Semaphore class class Process2 extends Thread { private static final Random rand = new Random(); private int id; private Semaphore sem; public Process2(int i, Semaphore s) { id = i; sem = s; } private void busy() { try { sleep(rand.nextInt(500)); } catch (InterruptedException e) { } } private void noncritical() { System.out.println("Thread " + id + " is NON critical"); busy(); } private void critical() { System.out.println("Thread " + id + " entering critical section"); busy(); System.out.println("Thread " + id + " leaving critical section"); Page 149 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS } public void run() { for (int i = 0; i < 2; ++i) { noncritical(); try { sem.acquire(); } catch (InterruptedException e) { // ... } critical(); sem.release(); } } public static void main(String[] args) { final int N = 4; System.out.println("Busy waiting..."); //Semaphore(int permits, boolean fair) Semaphore sem = new Semaphore(N, true); Process2[] p = new Process2[N]; for (int i = 0; i < N; i++) { p[i] = new Process2(i, sem); p[i].start(); } } } 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.

Page 150 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS For the java.util.concurrent class see CyclicBarrier A barrier is a type of synchronization method. A barrier for a group of threads or processes in the source code means any thread/process must stop at this point and cannot proceed until all other threads/processes reach this barrier.[1] The basic Java synchronization mechanism centers on the keyword synchronized, which predicates methods. In java, all objects can be used like monitors (protected types). That means that given an object A, no more than one thread can execute a synchronized method of A at any time. Barrier implementation /* * Given object A, no more than one thread can execute a synchronized method of A at any time. */ public class Barrier { public synchronized void block() throws InterruptedException { wait(); } public synchronized void release() throws InterruptedException { notify(); } public synchronized void releaseAll() throws InterruptedException { notifyAll(); } } And an example with two threads. class BarrierExample { static class MyThread1 implements Runnable { public MyThread1(Barrier barrier) { this.barrier = barrier; }

Page 151 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS public void run() { try { Thread.sleep(1000); System.out.println("MyThread1 waiting on barrier"); barrier.block(); System.out.println("MyThread1 has been released"); } catch (InterruptedException ie) { System.out.println(ie); } } private Barrier barrier; } static class MyThread2 implements Runnable { Barrier barrier; public MyThread2(Barrier barrier) { this.barrier = barrier; } public void run() { try { Thread.sleep(3000); System.out.println("MyThread2 releasing blocked threads\n"); barrier.release(); System.out.println("MyThread1 releasing blocked threads\n"); } catch (InterruptedException ie) { System.out.println(ie); } } } public static void main(String[] args) throws InterruptedException { Barrier BR = new Barrier(); Page 152 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS Thread t1 = new Thread(new BarrierExample.MyThread1(BR)); Thread t2 = new Thread(new BarrierExample.MyThread2(BR)); t1.start(); t2.start(); t1.join(); t2.join(); } } 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); } } class MakeString implements Runnable { Exchanger<String> ex; String str; MakeString(Exchanger<String> c) { ex = c; str = new String(); new Thread(this).start(); } public void run() { char ch = 'A'; Page 153 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS for (int i = 0; i < 3; i++) { for (int j = 0; j < 5; j++) str += (char) ch++; try { str = ex.exchange(str); } catch (InterruptedException exc) { System.out.println(exc); } } } } class UseString implements Runnable { Exchanger<String> ex; String str; UseString(Exchanger<String> c) { ex = c; new Thread(this).start(); } public void run() { for (int i = 0; i < 3; i++) { try { str = ex.exchange(new String()); System.out.println("Got: " + str); } catch (InterruptedException exc) { System.out.println(exc); } } } } Latches A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes. A CountDownLatch is initialized with a given count. The await methods block until the current count reaches zero due to Page 154 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS 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.*; public class LatchTest { private static final int COUNT = 10; private static class Worker implements Runnable { CountDownLatch startLatch; CountDownLatch stopLatch; String name; Worker(CountDownLatch startLatch, CountDownLatch stopLatch, String name) { this.startLatch = startLatch; this.stopLatch = stopLatch; this.name = name; } public void run() { try { startLatch.await(); // wait until the latch has counted down to // zero } catch (InterruptedException ex) { ex.printStackTrace(); } System.out.println("Running: " + name); stopLatch.countDown(); } }

Page 155 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS public static void main(String args[]) { // CountDownLatch(int count) // Constructs a CountDownLatch initialized with the given count. CountDownLatch startSignal = new CountDownLatch(1); CountDownLatch stopSignal = new CountDownLatch(COUNT); for (int i = 0; i < COUNT; i++) { new Thread(new Worker(startSignal, stopSignal, Integer.toString(i))) .start(); } System.out.println("Go"); startSignal.countDown(); try { stopSignal.await(); } catch (InterruptedException ex) { ex.printStackTrace(); } System.out.println("Done"); } } Thread and event driven programming: The single-thread rule: Here's the rule: Once a Swing component has been realized, all code that might affect or depend on the state of that component should be executed in the event-dispatching thread. This rule might sound scary, but for many simple programs, you don't have to worry about threads. Before we go into detail about how to write Swing code, let's define two terms: realized and event-dispatching thread. Realized means that the component's paint() method has been or might be called. A Swing component that's a top-level window is realized by having one of these methods invoked on it: setVisible(true), show(), or (this might surprise you) pack(). Once a window is realized, all components that it contains are realized. Another way to realize a component is to add it to a container that's already realized. You'll see examples of realizing components later. The event-dispatching thread is the thread that executes drawing and event-handling code. For example, the paint() and actionPerformed() methods are automatically executed

Page 156 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS in the event-dispatching thread. Another way to execute code in the event-dispatching thread is to use the SwingUtilities invokeLater() method.

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; public class InvokeAndWaitDemo extends Object { private static void print(String msg) { String name = Thread.currentThread().getName(); System.out.println(name + ": " + msg); } public static void main(String[] args) { final JLabel label = new JLabel("--------"); JPanel panel = new JPanel(new FlowLayout()); panel.add(label); JFrame f = new JFrame("InvokeAndWaitDemo"); f.setContentPane(panel); f.setSize(300, 100); f.setVisible(true); try { print("sleeping for 3 seconds"); Thread.sleep(3000); print("creating code block for event thread"); Runnable setTextRun = new Runnable() { public void run() { print("about to do setText()"); label.setText("New text!"); Page 157 of 158 Einstein college of engineering

CS55 PROGRAMMING PARADIGMS } }; 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()"); } } }

Page 158 of 158 Einstein college of engineering

You might also like