Anna University, Chennai
DHANALAKSHMI SRINIVASAN INSTITUTE OF RESEARCH AND TECHNOLOGY DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING
CS2305-PROGRAMMING PARADIGM-16MARKS
UNIT-I OBJECT ORIENTERD PROGRAMMING FUNDAMENDALS
1. Explain OOP Principles.
OOP is defined as object oriented programming. Basic Concepts of OOP
1) Class
2) Object
3) Method
4) Inheritance
5) Data Abstraction
6) Data Encapsulation
7) Polymorphism
8) Message Passing
Defining the Class:
A class is defined by the user is data type with the template that helps in defining the properties. Once the class type has been defined we can create the variables of that type using declarations that are similar to the basic type declarations. In java instances of the classes which are actual objects
Eg:
classclassname [extends superclassname]
{
[fields declarations;] [methods declaration;]
}
Field Declaration
Data is encapsulated in a class by placing data fields inside the body of the class definition. These variables are called as instance variables.
Class Rectangle
{
1
int length; int width;
}
Method Declaration
A Class with only data fields has no life, we must add methods for manipulating the data contained in the class. Methods are declared inside the class immediate after the instance variables declaration.
Eg:
class Rectangle
{
int length; //instance variables int width;
Void getData(int x, int y) // Method Declartion
{
Length =x; Width = y;
}
}
Creating the objects:
An object in java essentially a block of memory, which contains space to store all the instance
variables. Creating an object is also referred as instantiating an object. Object in java are created using the new operator. Eg:
Rectangle rec1; // Declare the object
Rec1 = new Rectangle //instantiate the object
The above statements can also be combined as follows
Rectangle rec1 = new Rectangle;
Methods:
Methods are similar to functions or procedures that are available in other programming languages.
Difference B/w methods and functions
Difference b/w method and function is method declared inside class, function can be declared anywhere inside are outside class
Writing methods in java
If we had to repeatedly output a header such as: System.out.println("GKMCET");
System.out.println ("Allapakkam"); System.out.println ("Meppedu Road"); We could put it all in a method like this: public static void printHeader()
{ System.out.println("GKMCET"); System.out.println("Allapakkam"); System.out.println("Meppedu Road");
}
Inheritance:
Inheritance is the process of forming a new class from an existing class or base class. The base class is also known as parent class or super class, the new class that is formed is called derived class. Derived class is also known as a child class or sub class. Inheritance helps in reducing the overall code size(reusability) of the program, which is an important concept in object-oriented programming.
Data Abstraction:
Data abstraction increases the power of programming language by creating user defined data types. Data abstraction also represents the needed information in the program without presenting the details.
Data Encapsulation:
Data encapsulation combines data and functions into a single unit called class. When using Data Encapsulation, data is not accessed directly; it is only accessible through the functions present inside the class. Data encapsulation enables the important concept of data hiding possible.
Polymorphism:
Polymorphism allows routines to use variables of different types at different times. An operator or function can be given different meanings or functions. The ability of objects to respond differently to the same message or function call.
Message passing:
A message passing system provides primitives for sending and receiving messages using objects. These primitives may by either synchronous or asynchronous or both.
2. Explain Constructors with examples.
Constructor:
Constructors are the method. It is used to give initial values to instance variables of the objects. It is automatically called at the time of object creation.
Syntax :
Constructor name(arguments)
{ Statements; Initial values;
}
Rules:
A constructor has the same name as the class. A class can have more than one constructor.
A constructor can take zero ,one ,or more parameters. A constructor has no return value.
A constructor is always called with the new operator.
Example program:
Class complex:
{
Float rp; Float ip;
Complex(float x,float y) //Defining Constructor
{ Rp=x; Ip=y;
}
Void print()
{
System.out.println(“Real part”=rp); System.out.println(“Imaginary part”+ip);
}
Void sum(complex a,complex b)
{ Rp=a.rp+b.rp; Ip=a.ip=b.ip;
}
}
Class demo
{
Public static void main(string args[]);
{
Complex a,b,c;
a=new complex(5,6); //Calling Constructor b=new complex(8,9);
c=new complex(); c.sum(a,b);
c.print();
}
}
3.Explain Packages in detail. Packages
Packages are java’s way of grouping a variety of classes and/or interfaces together. Packages are container for the classes .
It is the header file in c++.
It is stored in a hierarichical manner.
If we want to use the packages in a class, we want to import it. The two types of packages are:
1.System package. 2.User defined package.
Uses of Packages:
Packages reduce the complexity of the software because a large number of classes can be grouped into a limited number of packages.
We can create classes with same name in different packages. Using packages we can hide classes.
We may like to use many of the classes Import packagename .classname contained in a package.it can be achieved by:
Import packagename.* Creating the package
To create our own packages
Package name
packagefirstpackage;// package declaration public class FirstClass //class definition
{…..
(body of class)
…….}
The file is saved as FirstClass.java,located at firstpackage directory. when it is compiled .class file will be created in same ditectory.
Access a package
The import statement can be used to search a list of packages for a particular class. The general form of import statement for searching class is a as follows.
Import package1 [.package2] [.package3].classname;
Using the package package package1 ; public class classA
{
public void displayA()
{
System.out.println(“class A”);
}
}
Adding a class to package
Define the class and make it public Place the package statement Package P1
Before the class definition as follows
Package p1; Public class B
{
// body of B
} Example: Package college Class student
{ intregno; String name;
Student(intr,stringna);
{ Regno=r Name=na
}
Public void print()
{
System.out.println(“Regno”+regno ); System.out.println(“Name”+name );
}
}
Package Course
Class engineering
{ Intregno; String branch; String year;
Engineering(int r, string br, string yr)
{ Regno=br;
Branch=br; Year=yr;
}
public void print()
{ Systems.out.println(“Regno”+regno); Systems.out.println(“Branch”+branch); Systems.out.println(“Year”+year);
}
}
import college.*; import course.*; Class demo
{
Public static void main(string args[])
{
Student sl=new Engineering(1,”CSE”,”III Year”); Sl.print();
El.print();
}
}
4. What is Array?.How to declare array?Discuss the methods under Array Class. Arrays
An array is a data structure that stores a collection of values of the same type. You access each individual value through an integer index.
Array Name [index]
Integer constant, variable, or expression
For Instance we can define an array name salary to represent a set of salaries of a group of employees. A particular value is indicated by writing a number called index in brackets after the array name. 9
salary [10]
it represents the salary of the 10th employee. Types of arrays
One dimensional arrays Two dimensional arrays One Dimensional arrays
A list of items can be given one variable name using only one subscript and such a variable is called single- subscripted of one dimensional array. The subscript can also start from 0. ie x[0].
If we want to represent a set of five numbers, say (35,40,20,57,19) by an array variable number, then we have to create the variable number as follows
int number [ ] = new int [5 ];
The value to the array elements can be assigned as follows Number [0] =35; Number [1] =40;
Number [2] =20; Number [3] =57; Number [4] =19;
This would cause the array number to store the values shown as follows;
Creating an array
Declaring the array
Creating memory locations
Putting values into the memory locations. Declaring the Array
Array in java can be declared in two forms
Form 1 type arrayname [ ]; Form 2 type [ ] arrayname; Creation of arrays
arrayname = new type [ size ]; Eg;
number = new int [5] ; average = new float[10];
it is also possible to combine declaration and creation. int number [ ] = new int [5];
Initialization of arrays
The final step is to put values into the array created. This process is known as initialization using the array subscripts as shown below.
arrayname[subscript] = value ; Eg
number[0] = 15;
we can also initialize by following way typearrayname [ ] = { list of values }
Array Length
All array store the allocated size in an variable named length. We can obtain the length of array a using
a.length
Eg:
Int asize = a.length;
Sample Code for array manipulation
Two Dimensional arrary:
Usage :int myArray [ ] [ ];
myArray = new int [3] [4];
or
initmyArray [ ] [ ] = new int [3][4]
This creates a table that can store 12 integer values, four across and three down.
Strings:
Series of characters represents a string, and easiest way to represent the string is array
Eg:
Char charArray [ ] = new char [2] ; charArray[0] = ‘j’ ;
charArray[1] = ‘a’ ;
String can be declared and created in the following way string stringname;
stringname = new string (“string”);
Operations on string
int m = stringname.length() //will return the length of the string
string city = “New” + “Delhi”// will return New Delhi ,string concatinating
Sample Code for string manipulation
5. What is javaDoc? Explain the comments for classes, methods, fields and link.
Overview of Javadoc
The basic structure of writing document comments is embed them inside /** ... */. The Javadoc is written next to the items without any separating newline. The class declaration usually contains:
/**
* @author FirstnameLastname<address @ example.com>
*
@version 1.6 (The Java version used)
* @since 2010.0331 (E.g. ISO 8601 YYYY.MMDD)
*/
publicclass Test { // class body
}
For methods there is
(1) a short, concise, one line description to explain what the item does. This is followed by
(2) a longer description that may span in multiple paragraphs. In those the details can be explained in full. This section, marked in brackets [], is optional.
(3) a tag section to list the accepted input arguments and return values of the method. /**
* Short one line description.
*
* Longer description. If there were any, it would be here.
*
*@param variable Description text texttext.
*@return Description text texttext.
*/
Variables are documented similarly to methods with the exception that part (3) is omitted. Here the variable contains only the short description:
/**
* Description of the variable here.
*/
privateint debug =0;
Tag & Parameter Usage Applies to Since
@author name Describes an author. Class, Interface
@version version Provides version entry. Max one per Class, Interface
Class or Interface.
@since since-text
@see reference
@paramname description
Describes since when this functionality Class, Interface,
has existed. Field, Method
Provides a link to other element of Class, Interface, documentation. Field, Method
Describes a method parameter. Method
@return description Describes the return value. Method
@exception classname
description Describes an exception that may be
@throws classname thrown from this method.
description
Method
@deprecated description Describes an outdated method. Method
Copies the description from the
overridden method.
Overriding Method
Class, Interface,
{@link reference} Link to other symbol.
Field, Method
{@value} Return the value of a static field. Static Field
6.Illustrate with examples: static and final. Static Methods
The mean() method would work just as well if it wasn't declared static, as long as it was called from within the same class. If called from outside the class and it wasn't declared static, it would have to be qualified (uselessly) with an object. Even when used within the class, there are good reasons to define a method as static when it could be.
Documentation. Anyone seeing that a method is static will know how to call it. Similarly, any programmer looking at the code will know that a static method can't interact with instance variables, which makes reading and debugging easier.
Efficiency. A compiler will usually produce slightly more efficient code because no implicit object parameter has to be passed to the meth
Calling static methods There are two cases. Called from within the same class
Just write the static method name. Eg,
// Called from inside the MyUtils class doubleavgAtt = mean(attendance); Called from outside the class
If a method (static or instance) is called from another class, something must be given before the method name to specify the class where the method is defined. For instance methods, this is the object that the method will access. For static methods, the class name should be specified.
Eg,
// Called from outside the MyUtils class. doubleavgAtt = MyUtils.mean(attendance);
If an object is specified before it, the object value will be ignored and the the class of the object will be used.
Static Members
Let us assume that we want to define a member that is common to all the objects and can be accessed without using a particular object. That is the member belongs to the class as a whole rather than the objects created from the class.
It can be defined as follows staticint count; Static int max (int x, int y);
The members declared as static are known as static members.
Static variable are used when we want to have a variable common to all instances of class. Eg: Using static members
Final methods and variables
All method and variables can be overridden by default subclasses. If we wish to prevent the subclasses
from overriding the members of the superclass, we can declare them as final using the keyword final as a modifier.
Final int SIZE = 100; final void showstatus()
Making a method final ensures that the functionality defined in this method will never be altered in anyway, similarly the value of a final variable can never be changed.
Finalizer methods
In java we know that Garbage collector will automatically free the memory resources used by objects. But objects may hold othernon-object resources such as file descriptor or window system fonts. The Garbage collector cannot free those resources. To facilitate this java provides this finalizer method, similar to destructor in C++.
The finalizer method is simply finalize() and can be added to any class. Finalize method should explicitly specify the operation to be performed
7. Explain method overriding with example program.
A method is said to be overridden when one is in parent class and another is in child class with the same name, same return type, same parameter.
/ Method overriding. class A {
inti, j;
A(int a, int b) { i = a;
j = b;
}
// display i and j void show() {
System.out.println("i and j: " + i + " " + j);
}
}
class B extends A { int k;
B(int a, int b, int c) { super(a, b);
k = c;
}
// display k – this overrides show() in A void show() { System.out.println("k: " + k);
}
}
class Override {
public static void main(String args[]) { B subOb = new B(1, 2, 3); subOb.show(); // this calls show() in
B
}
}
The output produced by this program is shown here: k: 3
UNIT- II OBJECT ORIENTED PROGRAMMING - INHERITANCE
1. Explain the concept of inheritance and its types. Inheritance
The concept of inheritance is used to make the things from general to more specific e.g. When we hear the word vehicle then we got an image in our mind that it moves from one place to another place it is used for traveling or carrying goods but the word vehicle does not specify whether it is two or three or four wheeler because it is a general word.
But the word car makes a more specific image in mind than vehicle, that the car has four wheels. It concludes from the example that car is a specific word and vehicle is the general word.
If we think technically to this example then vehicle is the super class (or base class or parent class) and car is the subclass or child class because every car has the features of it's parent (in this case vehicle) class The following kinds of inheritance are there in java.
Simple Inheritance Multilevel Inheritance Simple Inheritance
When a subclass is derived simply from it's parent class then this mechanism is known as simple inheritance. In case of simple inheritance there is only a sub class and it's parent class. It is also called single inheritance or one level inheritance.
class A
{
int x; int y;
int get(int p, int q)
{
x=p; y=q; return(0);
}
void Show()
{ System.out.println(x);
}
}
class B extends A
{
public static void main(String args[]){ A a = new A();
a.get(5,6);
a.Show();
}
void display(){ System.out.println("B");
}
}
Multilevel Inheritance
It is the enhancement of the concept of inheritance. When a subclass is derived from a derived class then this mechanism is known as the multilevel inheritance. The derived class is called the subclass or child class for it's parent class and this parent class works as the child class for it's just above ( parent )
class. Multilevel inheritance can go up to any number of level.
class A { int x;
int y;
int get(int p, int q){ x=p; y=q; return(0);
}
void Show(){ System.out.println(x);
}
}
class B extends A{ void Showb(){ System.out.println("B");
}
}
class C extends B{ void display(){ System.out.println("C");
}
public static void main(String args[]){ A a = new A();
a.get(5,6);
a.Show();
}
}
Java does not support multiple Inheritance
Multiple Inheritances
The mechanism of inheriting the features of more than one base class into a single class is known as multiple inheritances. Java does not support multiple inheritances but the multiple inheritances can be achieved by using the interface.
2. Define an interface. Explain with example.
An interface in the Java programming language is an abstract type that is used to specify an interface (in the generic sense of the term) that classes must implement. Interfaces are declared using the interfacekeyword, and may only contain method signature and constant declarations (variable declarations that are declared to be both static and final). An interface may never contain method definitions.
In Java Multiple Inheritance can be achieved through use of Interfaces by implementing more than one interface in a class.
Multiple inheritance using interfaces to calculate the area of a rectangle and triangle
/* Area Of Rectangle and Triangle using Interface * /
interface Area
{
float compute(float x, float y);
}
class Rectangle implements Area
{
public float compute(float x, float y)
{
return(x * y);
}}
class Triangle implements Area
{
public float compute(float x,float y)
{
return(x * y/2);
}
}
class InterfaceArea
{
public static void main(String args[])
{
Rectangle rect = new Rectangle(); Triangle tri = new Triangle(); Area area;
area = rect;
System.out.println("Area Of Rectangle = "+ area.compute(1,2));
area = tri;
System.out.println("Area Of Triangle = "+ area.compute(10,2));
}
}
/** OUTPUT **
Area Of Rectangle = 2.0 Area Of Triangle = 10.0 */
3. What is dynamic binding? Explain with example. Java 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.
When the compiler can't determine which method implementation to use in advance, the runtime system (JVM) selects the appropriate method at runtime, based on the class of the object. This mechanism is known as dynamic binding.
class Shape{ publicvoid draw() { System.out.println(“\n\tDrawing a shape.”);
}
} classCircleextendsShape{ publicvoiddraw() {
System.out.println(“\n\tDrawing a Circle.”);
}
}
class Rectangle extends Shape{ publicvoid draw() { System.out.println(“\n\tDrawing a Rectangle.”);
}
} publicclassDynamicBindingDemo{ publicstaticvoid main(String args[]) { Shape obj;
obj = new Shape();
obj.draw();
obj = new Circle();
obj.draw();
obj = new Rectangle();
obj.draw();
}
}
Result:
Drawing a shape. Drawing a Circle. Drawing a Rectangle.
4. Explain the uses of reflection with examples. Reflection
When you look in a mirror: - You can see your reflection
In computer programming:
- Reflection is infrastructure enabling a program can see and manipulate itself - It consists of metadata
plus operations to manipulate the metadata
Meta means self-referential
- So metadata is data (information) about oneself
Reflections on a class
The Class object gives you all the basic hooks for reflection access to the class metadata. This metadata includes information about the class itself, such as the package and superclass of the class, as well as the interfaces implemented by the class.
It also includes details of the constructors, fields, and methods defined by the class. These last items are the ones most often used in programming,
For each of these three types of class components -- constructors, fields, and methods -- the java.lang.Class provides four separate reflection calls to access information in different ways. The calls all follow a standard form.
Here's the set used to find constructors:
Constructor getConstructor(Class[] params) -- Gets the public constructor using the specified parameter types
Constructor[] getConstructors() -- Gets all the public constructors for the class
Constructor getDeclaredConstructor(Class[] params) -- Gets the constructor (regardless of access level) using the specified parameter types
Constructor[] getDeclaredConstructors() -- Gets all the constructors (regardless of access level) for the class
Listing 1. Class constructed from pair of strings public class TwoString { private String m_s1, m_s2; publicTwoString(String s1, String s2) { m_s1 = s1;
m_s2 = s2;
}
}
The code shown in Listing 2 gets the constructor and uses it to create an instance of the TwoString class using Strings "a" and "b":
Listing 2. Reflection call to constructor
Class[] types = new Class[] { String.class, String.class }; Constructor cons = TwoString.class.getConstructor(types); Object[] args = new Object[] { "a", "b" };
TwoStringts = (TwoString)cons.newInstance(args);
The code in Listing 2 ignores several possible types of checked exceptions thrown by the various reflection methods.
Object newInstance() -- Constructs new instance using default constructor
Even though this approach only lets you use one particular constructor, it makes a very convenient shortcut if that's the one you want. This technique is especially useful when working with JavaBeans, which are required to define a public, no-argument constructor.
Fields by reflection
The Class reflection calls to access field information are similar to those used to access constructors, with a field name used in place of an array of parameter types:
Field getField(String name) -- Gets the named public field Field[] getFields() -- Gets all public fields of the class
Field getDeclaredField(String name) -- Gets the named field declared by the class Field[]
getDeclaredFields() -- Gets all the fields declared by the class
Despite the similarity to the constructor calls, there's one important difference when it comes to fields
|
The last two return information for fields declared directly by the class -- regardless of the fields' access types.
The java.lang.reflect.Field instances returned by the calls define getXXX and setXXX methods for all the primitive types, as well as generic get and set methods that work with object references.
Listing 3 shows an example of using the field reflection methods, in the form of a method to increment an int field of an object by name:
Listing 3
publicintincrementField(String name, Object obj) throws... { Field field =
obj.getClass().getDeclaredField(name);
int value = field.getInt(obj) + 1; field.setInt(obj, value);
return value;
}
This method starts to show some of the flexibility possible with reflection. Rather than working with a specific class, incrementField uses the getClass method of the passed in object to find the class information, then finds the named field directly in that class.
Methods by reflection
The Class reflection calls to access method information are very similar to those used for constructors and fields:
Method getMethod(String name, Class[] params) -- Gets the named public method using the specified parameter types
Method[] getMethods() -- Gets all public methods of the class
Method getDeclaredMethod(String name, Class[] params) -- Gets the named method declared by the class using the specified parameter types
Method[] getDeclaredMethods() -- Gets all the methods declared by the class importjava.lang.reflect.*;
public class DumpMethods {
public static void main(String args[])
{
try {
Class c = Class.forName(args[0]); Method m[] = c.getDeclaredMethods();
for (inti = 0; i<m.length; i++) System.out.println(m[i].toString());
}
catch (Throwable e) { System.err.println(e);
}
}
}
5.With an example explain proxies Proxies
Proxies are only necessary when you don’t yet know at compile time which interfaces you need to implement.
Suppose you want to construct an object of a class that implements one or more interfaces whose exact nature you may not know at compile time.
To construct an actual class, you can simply use the newInstance method or use reflection to find a constructor. But you can’t instantiate an interface. You need to define a newclass in a running program.
To overcome this problem, some programs generate code, place it into a file, invoke the compiler, and then load the resulting class file. Naturally, this is slow, and it also requires deployment of the compiler together with the program.
The proxy mechanism is a better solution. 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; and
All methods defined in the Object class (toString, equals, and so on).
However, you cannot define new code for these methods at runtime. Instead, you must supply an invocation handler. An invocation handler is an object of any class that implements the InvocationHandler interface. That interface has a single method:
Object invoke(Object proxy, Method method, Object[] args)
Whenever a method is called on the proxy object, the invoke method of the invocationhandler gets called, with the Method object and parameters of the original call. The invocationhandler must then figure out how to handle the call.
To create a proxy object, you use the newProxyInstance method of the Proxy class. The method has three parameters:
A class loader. As part of the Java security model, different class loaders for system classes, classes that are downloaded from the Internet, and so on, can be used.
An array of Class objects, one for each interface to be implemented. An invocation handler. There are two remaining questions. How do we define the handler? And what can we do
with the resulting proxy object? The answers depend, of course, on the problem that we want to solve with the proxy mechanism.
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; and
Tracing method calls for debugging purposes.
6. Abstract
As you move up the inheritance hierarchy, classes become more general and probably more abstract. At some point, the ancestor class becomes so general that you think of it more as a basis for other classes than as a class with specific instances you want to use.
Consider, for example, an extension of our Employee class hierarchy. An employee is a person, and so is a student. Let us extend our class hierarchy to include classes Person and Student. The following
Why bother with so high a level of abstraction? There are some attributes that make sense for every person, such as the name. Both students and employees have names and introducing a common superclass lets us factor out the getName method to a higher level in the inheritance hierarchy. Now let’s add another method, getDescription, whose purpose is to return a brief description of the person, such as an employee with
a salary of $50,000.00,
a student majoring in computer science.
It is easy to implement this method for the Employee and Student classes. But what information can you provide in the Person class? The Person class knows nothing about the person except the name. Of course, you could implement Person.getDescription() to return an empty string. But there is a better way. If you use the abstract keyword, you do not need to implement the method at all.
publicabstract String getDescription(); // no implementation required
For added clarity, a class with one or more abstract methods must itself be declared abstract.
abstractclass Person { . . . publicabstract String getDescription();
}
In addition to abstract methods, abstract classes can have fields and concrete methods. For example, the Person class stores the name of the person and has a concrete method
that returns it. abstract class Person
{
public Person(String n)
{
name = n;
}
public abstract String getDescription(); public String getName()
{
return name;
}
private String name;
}
Abstract Classes
Abstract methods act as placeholders for methods that are implemented in the subclasses.When you extend an abstract class, you have two choices. You can leave some or all of the abstract methods undefined.
Then you must tag the subclass as abstract as well. Or you can define all methods. Then the subclass is no longer abstract.
For example,
we will define a Student class that extends the abstract Person class and implements the get Description method. Because none of the methods of the Student class are abstract, it does not need to be declared as an abstract class.
A class can even be declared as abstract even though it has no abstract methods. Abstract classes cannot be instantiated. That is, if a class is declared as abstract, no objects of that class can be created.
For example, the expression
new Person("Vince Vu")is an error. However, you can create objects of concrete subclasses.
Note that you can still create object variables of an abstract class, but such a variable must refer to an object of a nonabstract subclass.
For example:
Person p = new Student("Vince Vu", "Economics");
Here p is a variable of the abstract type Person that refers to an instance of the nonabstract subclass
Student
Let us define a concrete subclass Student that extends the abstract Person class: class Student extends
Person
{
public Student(String n, String m) super(n);
major = m;
}
public String getDescription()
{
return "a student majoring in " + major;
}
private String major;
}
The Student class defines the getDescription method. Therefore, all methods in the Student class are concrete, and the class is no longer an abstract class.
class Employee extends Object.
The ultimate superclass Object is taken for granted if no superclass is explicitly mentioned. Because every class in Java extends Object, it is important to be familiar with the services provided by the Object class.
Object obj = new Employee("Harry Hacker", 35000);
Of course, a variable of type Object is only useful as a generic holder for arbitrary values.To do anything specific with the value, you need to have some knowledge about the original type and then apply a cast:
Employee e = (Employee) obj;
In Java, only the primitive types (numbers, characters, and boolean values) are not objects.All array types, no matter whether they are arrays of objects or arrays of primitive
types, are class types that extend the Object class. Employee[] staff = new Employee[10]; obj = staff; // OK obj = new int[10];
UNIT-III EVENT DRIVEN PROGRAMMING
1.Explain the classes under 2D shapes. Working with 2D Shapes
Starting with Java 1.0, the Graphics class had methods to draw lines, rectangles, ellipses, and so on. But those drawing operations are very limited. For example, you cannot vary the line thickness and you cannot rotate the shapes.
To draw shapes in the Java 2D library, you need to obtain an object of the Graphics2D class. This class is a subclass of the Graphics class. Ever since Java SE 2, methods such as paint Component automatically
receive an object of the Graphics2D class. Simply use a cast, as follows: public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
. . .
}
The Java 2D library organizes geometric shapes in an object-oriented fashion. In particular, there are classes to represent lines, rectangles, and ellipses:
Line2D Rectangle2D Ellipse2D
These classes all implement the Shape interface
To draw a shape, you first create an object of a class that implements the Shape interface and then call the draw method of the Graphics2D class.
For example: Rectangle2D rect = . . .;
g2.draw(rect);
The RectangularShape class defines over 20 methods that are common to these shapes, among them such useful methods as
getWidth getHeight getCenterX
getCenterY.
The Rectangle and Point classes, which store a rectangle and a point with integer coordinates, extend the Rectangle2D and Point2D classes.
Rectangle2D and Ellipse2D objects are simple to construct. You need to specify
• The x- and y-coordinates of the top-left corner; and
• The width and height.
For ellipses, these refer to the bounding rectangle. For example,
Ellipse2D e = new Ellipse2D.Double(150, 200, 100, 50);
constructs an ellipse that is bounded by a rectangle with the top-left corner at (150, 200), width 100, and height 50.
API java.awt.geom.Rectangle2D.Double
• Rectangle2D.Double(double x, double y, double w, double h) Constructs a rectangle with the given top-left corner, width, and height. API ava.awt.geom.Ellipse2D.Double
• Ellipse2D.Double(double x, double y, double w, double h)
Constructs an ellipse whose bounding rectangle has the given top-left corner, width, and height.
2.Explain event handling with examples. EVENT HANDLING
Event-driven programming usually has a pretty large impact on the design of a program. Usually, a program has to be broken up into separate pieces to do event-drive programming.
Event-driven programming in Java is more complicated than non-event driven. But it makes far more efficient use of the hardware and sometimes (like when developing a graphical user interface) dividing your code up into event-driven blocks actually fits very naturally with your program's structure.
Different event sources can produce different kinds of events. For example, a button can send
ActionEvent objects, whereas a window can send WindowEvent objects.
Here is an overview of how event handling in the AWT works:
A listener object is an instance of a class that implements a special interface called 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.
Here is an example for specifying a listener
ActionListener listener = . . .; JButton button = new JButton("Ok");
button.addActionListener(listener);
Now the listener object is notified whenever an “action event” occurs in the button. For buttons, as you might expect, an action event is a button click.
To implement the ActionListener interface, the listener class actionPerformed that receives an ActionEvent object as a parameter. | must | have | a | method | called |
classMyListener implements ActionListener | |||||
{ | |||||
. . . | |||||
public void actionPerformed(ActionEvent event) | |||||
{ | |||||
// reaction to button click goes here | |||||
. . . } | |||||
} |
Whenever the user clicks the button, the JButton object creates an ActionEvent object and calls listener.actionPerformed(event), passing that event object. An event source such as a button can have multiple listeners. In that case, the button calls the actionPerformed methods of all listeners whenever the user clicks the button.
Example: Handling a Button Click
Let’s work through all details needed for the simple example of responding to a button click. For this example, we will show a panel populated with three buttons.
Three listener objects are added asaction listeners to the buttons.
With this scenario, each time a user clicks on any of the buttons on the panel, the associated listener object then receives an ActionEvent that indicates a button click. In
our sample program, the listener object will then change the background color of the panelWe need to add code that listens to these buttons. This requires classes that implement the ActionListener interface, which, as we just mentioned, has one method: actionPerformed, whose signature looks like this:
public void actionPerformed(ActionEvent event)
When a button is clicked, we want the background color of the panel to change to a particular color. We store the desired color in our listener class.
classColorAction implements ActionListener
{
publicColorAction(Color c)
{
backgroundColor = c;
}
public void actionPerformed(ActionEvent event)
{
// set panel background color
. . .
}
private Color backgroundColor;
}
3.Explain action event with an example. Actions
It is common to have multiple ways to activate the same command. The user can choose a certain function through a menu, a keystroke, or a button on a toolbar. This is easy to achieve in the AWT event model: link all events to the same listener.
\ For example, supposeblueAction is an action listener whose actionPerformed method changes the background color to blue. You can attach the same object as a listener to several event sources:
Then the color change command is handled in a uniform way, no matter whether it was caused by a button click, a menu selection, or a key press.
The Swing package provides a very useful mechanism to encapsulate commands and to attach them to multiple event sources: the Action interface.
An action is an object that encapsulates
• A description of the command (as a text string and an optional icon); and
• Parameters that are necessary to carry out the
The Action interface has the following methods:
voidactionPerformed(ActionEvent event) voidsetEnabled(boolean b) booleanisEnabled()
voidputValue(String key, Object value) Object getValue(String key)
voidaddPropertyChangeListener(PropertyChangeListener listener)
voidremovePropertyChangeListener(PropertyChangeListener listener)
The first method is the familiar method in the ActionListener interface: in fact, the Action interface extends the ActionListener interface. Therefore, you can use an Action object whenever an ActionListener object is expected.
The next two methods let you enable or disable the action and check whether the action is currently enabled. When an action is attached to a menu or toolbar and the action is disabled, then the option is grayed out.
The putValue and getValue methods let you store and retrieve arbitrary name/value
pairs in the action object. A couple of important predefined strings, namely, Action.NAME and
Action.SMALL_ICON, store action names and icons into an action object: action.putValue(Action.NAME, "Blue"); action.putValue(Action.SMALL_ICON, new ImageIcon("blue-ball.gif")); Mouse Events
You do not need to handle mouse events explicitly if you just want the user to be able to click on a button or menu.
These mouse operations are handled internally by the various components in the user interface. However, if you want to enable the user to draw with the mouse, you will need to trap mouse move, click, and drag events
When the user clicks a mouse button, three listener methods are called: mousePressed when the mouse is first pressed, mouseReleased when the mouse is released, and, finally, mouse-Clicked.
If you are only interested in complete clicks, you can ignore the first two methods.By using the getX and getY methods on the MouseEvent argument, you can obtain the xandy-coordinates of the mouse pointer when the mouse was clicked.
To distinguishbetween single, double, and triple (!) clicks, use the getClickCount method.
You use bit masks to test which modifiers have been set. In the original API, two of the button masks equal two keyboard modifier masks, namely
BUTTON2_MASK == ALT_MASK BUTTON3_MASK == META_MASK
This was done so that users with a one-button mouse could simulate the other mouse buttons by holding down modifier keys instead. There are now masks BUTTON1_DOWN_MASK
BUTTON2_DOWN_MASK
BUTTON3_DOWN_MASK SHIFT_DOWN_MASK CTRL_DOWN_MASK ALT_DOWN_MASK ALT_GRAPH_DOWN_MASK META_DOWN_MASK
The getModifiersEx method accurately reports the mouse buttons and keyboard modifiers of a mouse event.
Note that BUTTON3_DOWN_MASK tests for the right (nonprimary) mouse button under Windows. For example, you can use code like this to detect whether the right mouse button is down:
if ((event.getModifiersEx() & InputEvent.BUTTON3_DOWN_MASK) != 0)
. . . // code for right click
In our sample program, we supply both a mousePressed and a mouseClicked method.. public void mousePressed(MouseEvent event)
{
current = find(event.getPoint());
if (current == null) // not inside a square add(event.getPoint());
}
public void mouseClicked(MouseEvent event)
{
current = find(event.getPoint());
if (current != null &&event.getClickCount() >= 2) remove(current);
}
4.What are the swing components? Explain. Swing Component
It describes every Swing component. It assumes that you have successfully compiled and run a program that uses Swing components, and that you are familiar with basic Swing concepts.
Using Top-Level Containers
Discusses how to use the features shared by the JFrame, JDialog, and JApplet classes — content panes, menu bars, and root panes. It also discusses the containment hierarchy, which refers to the tree of components contained by a top-level container.
The JComponent Class
Tells you about the features JComponent provides to its subclasses — which include almost all Swing components — and gives tips on how to take advantage of these features. This section ends with API tables describing the commonly used API defined by JComponent and its superclasses, Container and Component.
Using Text Components
Describes the features and API shared by all components that descend from JTextComponent. You probably do not need to read this section if you are just using text fields.
How to work with it
It is recommend reading the relevant this, sections, once you are ready to start using Swing components in your own programs. For example, if your program needs a frame, a label, a button, and a color chooser, you should read How to Make Frames, How to Use Labels, How to Use Buttons, and
How to Use Color Choosers.
Using Models
Tells you about the Swing model architecture. This variation on Model-View-Controller (MVC) means that you can, if you wish, specify how the data and state of a Swing component are stored and retrieved. The benefits are the ability to share data and state between components, and to greatly improve the performance of components such as tables that display large amounts of data.
Using Borders
Borders are very handy for drawing lines, titles, and empty space around the edges of components. (You might have noticed that the examples in this trail use a lot of borders.) This section tells you how to add a border to any JComponent.
Using Icons
Many Swing components can display icons. Usually, icons are implemented as instances of the
ImageIcon class.
Eg: for Button.
To get the action command from an action event, call the event's getActionCommand( ) method. The following code checks whether the user pressed the Yes button:
public void actionPerformed(ActionEvent e){ if (e.getActionCommand( ).equals("Yes") {
//the user pressed "Yes"; do something
...
}
}
5.Describe the AWT event hierarchy. The AWT Event Hierarchy
As we briefly mentioned earlier, event handling in Java is object oriented, with all events descending from the EventObject class in the java.util package. (The common superclass is not called Event because that is the name of the event class in the old event model. Although the old model is now deprecated, its classes are still a part of the Java library.)
The EventObject class has a subclass AWTEvent, which is the parent of all AWT event classes. Following figure shows the inheritance diagram of the AWT events.
6.Explain the advantage and explain the methods in Model view controller The Model-View- Controller Design Pattern
As promised, we with describing the architecture of Swing components. We first discuss the concept of design patterns and then look at the “model- view- controller” pattern that has greatly influenced the design of the Swing framework
Design Patterns
Design patterns are a method for presenting this expertise in a structured way.
In the “model-view-controller” pattern, which we will describe in the next section, the context is a user interface system that presents information and receives user input.
There are several forces. There may be multiple visual representations of the same data that need to be updated together
The model-view-controller pattern is not the only pattern used in the design of AWT and Swing. Here are several additional examples:
Containers and components are examples of the “composite” pattern.
The scroll pane is a “decorator.”
Layout managers follow the “strategy” pattern.
One important aspect of design patterns is that they become part of the culture.
The Model-View-Controller Pattern
Let’s step back for a minute and think about the pieces that make up a user interface, component such as a button, a checkbox, a text field, or a sophisticated tree control.
Every component has three characteristics:
Its content, such as the state of a button (pushed in or not), or the text in a text field
Its visual appearance (color, size, and so on) Its behavior (reaction to events)
A Model-View-Controller Analysis of Swing Buttons
For most components, the model class implements an interface whose name ends in Model; thus the interface called ButtonModel. Classes implementing that interface can define the state of the various kinds of buttons. Actually, buttons aren’t all that complicated, and the Swing library contains a single class, called DefaultButtonModel, that implements this interface.
Each JButton object stores a button model object, which you can retrieve.
JButton button = new JButton("Blue"); ButtonModel model = button.getModel();
7.Give the methods available in graphics for COLOR and FONTS Color and fonts
Using Color
The setPaint method of the Graphics2D class lets you select a color that is used for all subsequent drawing operations on the graphics context. For example:
g2.setPaint(Color.RED);
g2.drawString("Warning!", 100, 100);
You can fill the interiors of closed shapes (such as rectangles or ellipses) with a color. Simply call fill instead of draw:
Rectangle2D rect = . . .;
g2.setPaint(Color.RED);
g2.fill(rect); // fills rect with red color
To draw in multiple colors, you select a color, draw or fill, then select another color, and draw or fill again.
You define colors with the Color class. The java.awt.Color class offers predefined constants for the following 13 standard colors:
BLACK, BLUE, CYAN, DARK_GRAY, GRAY, GREEN, LIGHT_GRAY, MAGENTA, ORANGE, PINK, RED, WHITE, YELLOW
You can specify a custom color by creating a Color object by its red, green, and blue components.
Using a scale of 0–255 (that is, one byte) for the redness, blueness, and greenness, call the Color constructor like this:
Color(int redness, int greenness, int blueness)
Here is an example of setting a custom color:
g2.setPaint(new Color(0, 128, 128)); // a dull blue-green g2.drawString("Welcome!", 75, 125);
To set the background color, you use the setBackground method of the Component class, an ancestor of JComponent.
MyComponent p = new MyComponent();p.setBackground(Color.PINK);
There is also a set Foreground method. It specifies the default color that is used for drawing on the component.
Using Fonts for Text
You specify a font by its font face name. A font face name is composed of a font family name, such as
“Helvetica,” and an optional suffix such as “Bold.” For example, the font faces “Helvetica”
and“Helvetica Bold” are both considered to be part of the family named “Helvetica.”
To find out which fonts are available on a particular computer, call the getAvailable- FontFamilyNames method of the GraphicsEnvironment class.the following program prints the names of all fonts on your system:
Import java.awt.*;
public class ListFonts
{
public static void main(String[] args)
{
String[] fontNames = GraphicsEnvironment
.getLocalGraphicsEnvironment()
.getAvailableFontFamilyNames(); for (String fontName : fontNames) System.out.println(fontName);
}
}
To establish a common baseline, the AWT defines five logical font names: SansSerif
Serif Monospaced Dialog DialogInput
These names are always mapped to fonts that actually exist on the client machine. For example, on a
Windows system, SansSerif is mapped to Arial.
UNIT –IV GENERIC PROGRAMMING
1. What is Generic Programming? Explain the use of Generic class and Generic methods. Generic Programming- Motivation
Generics are desirable because they let you write code that is safer and easier to read than code that is littered with Object variables and casts. Generics are particularly useful for collection classes, such as the ubiquitous ArrayList
Generics are—at least on the surface—similar to templates in C++. In C++, as in Java, templates were first added to the language to support strongly typed collections
Why Generic Programming?
Generic programming means to write code that can be reused for objects of many different types. For example, you don’t want to program separate classes to collect String and File objects. And you don’t have to—the single class ArrayList collects objects of any class.
This is one example of generic programming.
Before Java SE 5.0, generic programming in Java was always achieved with inheritance.TheArrayList class simply maintained an array of Object references:
public class ArrayList // before Java SE 5.0
{
public Object get(inti) { . . . } public void add(Object o) { . . . }
. . .
private Object[] elementData;
}
This approach has two problems. A cast is necessary whenever you retrieve a value: ArrayList files =
new ArrayList();
. . .
String filename = (String) names.get(0);
Moreover, there is no error checking. You can add values of any class: files.add(new File(". . ."));
This call compiles and runs without error. Elsewhere, casting the result of get to a String will cause an error.
Generics offer a better solution: type parameters. The ArrayList class now has a type parameter that indicates the element type:
ArrayList<String> files = new ArrayList<String>();
This makes your code easier to read. You can tell right away that this particular array list contains
String objects.
The compiler can make good use of this information too. No cast is required for calling get. The compiler knows that the return type is String, not Object:
String filename = files.get(0);
The compiler also knows that the add method of an ArrayList<String> has a parameter of type String. That is a lot safer than having an Object parameter. Now the compiler can check that you don’t insert objects of the wrong type.
For example, the statement
files.add(new File(". . .")); // can only add String objects to an ArrayList<String>
will not compile. A compiler error is much better than a class cast exception at runtime. This is the appeal of type parameters: they make your programs easier to read and safer.
Generic Class
A generic class is a class with one or more type variables.
This class allows us to focus on generics without being distracted by data storage details. Here is the code for the generic Pair class:
public class Pair<T>
{
public Pair() { first = null; second = null; }
public Pair(T first, T second) { this.first = first; this.second = second; } public T getFirst() { return first; }
public T getSecond() { return second; }
public void setFirst(T newValue) { first = newValue; } public void setSecond(T newValue) { second
= newValue; } private T first;
private T second;
}
The Pair class introduces a type variable T, enclosed in angle brackets <>, after the class name. A
generic class can have more than one type variable.
For example, we could have defined the Pair class with separate types for the first and second field:
public class Pair<T, U> { . . . }
The type variables are used throughout the class definition to specify method return types and the types of fields and local variables.
For example:
private T first; // uses type variable
Generic Methods
In the preceding section, you have seen how to define a generic class. You can also define a single method with type parameters.
classArrayAlg
{
public static <T> T getMiddle(T[] a)
{
return a[a.length / 2];
}
}
This method is defined inside an ordinary class, not inside a generic class. However, it is a generic method, as you can see from the angle brackets and the type variable.
Note that the type variables are inserted after the modifiers (public static, in our case) and before the
return type.
You can define generic methods both inside ordinary classes and inside generic classes. When you call a generic method, you can place the actual types,enclosed in angle brackets, before the method name: String[] names = { "John", "Q.", "Public" };
String middle = ArrayAlg.<String>getMiddle(names); In this case (and indeed in most cases), you can omit the <String> type parameter from the method call. The compiler has enough information to infer the method that you want. It matches the type of names (that is, String[]) against the generic type T[] and deduces that T must be String. That is, you can simply call String middle = ArrayAlg.getMiddle(names);
2. What is Inheritance? Inheritance and Generic-part I
When you work with generic classes, you need to learn a few rules about inheritance and subtypes. Let’s start with a situation that many programmers find unintuitive.
Consider a class and a subclass, such as Employee and Manager. Is Pair<Manager> a subclass ofPair<Employee>? Perhaps surprisingly, the answer is “no.”
For example, the following codewill not compile: Manager[] topHonchos = . . .; Pair<Employee> result = ArrayAlg.minmax(topHonchos); // ERROR
The minmax method returns a Pair<Manager>, not a Pair<Employee>, and it is illegal to assign one to the other.In general, there is no relationship between Pair<S> and Pair<T>, no matter how S and T are Related.
Suppose we were allowed to convert a Pair<Manager> to a Pair<Employee>. Consider this code: Pair<Manager>managerBuddies = new Pair<Manager>(ceo, cfo); Pair<Employee>employeeBuddies
= managerBuddies; // illegal, but suppose it wasn't employeeBuddies.setFirst(lowlyEmployee);
Clearly, the last statement is legal. But employeeBuddies and managerBuddies refer to the sameobject. You can always convert a parameterized type to a raw type.
For example, Pair<Employee>is a subtype of the raw type Pair. This conversion is necessary for interfacing with legacy code.
Can you convert to the raw type and then cause a type error? Unfortunately, you can. Consider this example:
Pair<Manager>managerBuddies = new Pair<Manager>(ceo, cfo); Pair rawBuddies =
managerBuddies; // OK
rawBuddies.setFirst(new File(". . .")); // only a compile-time warning The security of the virtual machine is not at stake. When the foreign object is retrieved with getFirst and assigned to a Manager variable, a ClassCastException is thrown, just as in the good old days.
You merely lose the added safety that generic programming normally provides. Finally, generic classes can extend or implement other generic classes.
3. Explain about Wildcard and its types? Wildcard
It was known for some time among researchers of type systems that a rigid system of generic types is quite unpleasant to use. The Java designers invented an ingenious (butnevertheless safe) “escape hatch”: the wildcard type. For example, the wildcard type
Pair<?extends Employee
Denotes any generic Pair type whose type parameter is a subclass of Employee, such as
Pair<Manager>, but not Pair<String>.
Let’s say you want to write a method that prints out pairs of employees, like this:
public static void printBuddies(Pair<Employee> p)
{
Employee first = p.getFirst(); Employee second = p.getSecond(); System.out.println(first.getName() + " and " + second.getName() + " are buddies.";
}
As you saw in the preceding section, you cannot pass a Pair<Manager> to that method, which is rather limiting. But the solution is simple—uses a wildcard type:
public static void printBuddies(Pair<? extends Employee> p)
Supertype Bounds for Wildcards
Wildcard bounds are similar to type variable bounds, but they have an added capability— you can specify a supertype bound, like this:
? super Manager
This wildcard is restricted to all supertypes of Manager.
Why would you want to do this? You can supply parameters to methods, but you can’t use the return values.
For example, Pair<? super Manager> has methods voidsetFirst(? super Manager) ? super Manager getFirst()
The compiler doesn’t know the exact type of the setFirst method but can call it with any object of type
Manager, Employee, or Object, but not a subtype such as Executive.
Intuitively speaking, wildcards with supertype bounds let you write to a generic object, wildcards with subtype bounds let you read from a generic objects.
Here is another use for supertype bounds. The Comparable interface is itself a generic type. It is declared as follows:
public interface Comparable<T>
{
publicintcompareTo(T other);
}
Here, the type variable indicates the type of the other parameter. For example, the String class implements Comparable<String>, and its compareTo method is declared as
publicintcompareTo(String other)
Because Comparable is a generic type, perhaps we should have done a better job with the min method of the ArrayAlg class? We could have declared it as
public static <T extends Comparable<T>> T min(T[] a)
This looks more thorough than just using T extends Comparable, and it would work fine for many classes.
Unbounded Wildcards
You can even use wildcards with no bounds at all, for example, Pair<?>. At first glance, this looks identical to the raw Pair type. Actually, the types are very different. The type Pair<?> has methods
such as
? getFirst() voidsetFirst(?)
The return value of getFirst can only be assigned to an Object. The setFirst method can
never be called, not even with an Object. That’s the essential difference between Pair<?> andair: you can call the setObject method of the raw Pair class with any Object.
For example, the following method tests whether a pair contains a given object. It never needs the actual type.
public static booleanhasNulls(Pair<?> p)
{
returnp.getFirst() == null || p.getSecond() == null;
}
You could have avoided the wildcard type by turning contains into a generic method: public static
<T>booleanhasNulls(Pair<T> p)
However, the version with the wildcard type seems easier to read.
Wildcard Capture
Let us write a method that swaps the elements of a pair: public static void swap(Pair<?> p)
A wildcard is not a type variable, so we can’t write code that uses ?as a type. In other words, the following would be illegal:
? t = p.getFirst(); // ERROR p.setFirst(p.getSecond()); p.setSecond(t);
That’s a problem because we need to temporarily hold the first element when we do the Swapping. We can write a helper method, swapHelper, like this:
public static <T> void swapHelper(Pair<T> p)
{
T t = p.getFirst(); p.setFirst(p.getSecond()); p.setSecond(t);
}
Note that swapHelper is a generic method, whereas swap is not—it has a fixed parameter of type
Pair<?>.
Now we can call swapHelper from swap:
public static void swap(Pair<?> p) { swapHelper(p); }
In this case, the parameter T of the swapHelper method captures the wildcard.
It isn’t known what type the wildcard denotes, but it is a definite type, and the definition of
<T>swapHelper makes perfect sense when T denotes that type.
4. What is Reflection and how to use reflection using Generic class? Reflection and Generics
The Class class is now generic. For example, String.class is actually an object (in fact, the sole object)
of the class Class<String>.
The type parameter is useful because it allows the methods of Class<T> to be more specific about their return types. The following methods of Class<T> take advantage of the
type parameter: T newInstance()
T cast(Object obj)
T[] getEnumConstants() Class<?super T>getSuperclass() Constructor<T>getConstructor(Class... parameterTypes) Constructor<T>getDeclaredConstructor(Class... parameterTypes)
The newInstance method returns an instance of the class, obtained from the default constructor. Its return type can now be declared to be T, the same type as the class that is being described by Class<T>.
Using Class<T> Parameters for Type Matching
It is sometimes useful to match the type variable of a Class<T> parameter in a generic method. Here is the canonical example:
public static <T> Pair<T>makePair(Class<T> c) throws InstantiationException, IllegalAccessException
{
return new Pair<T>(c.newInstance(), c.newInstance());
}
If you call makePair(Employee.class) then Employee.class is an object of type Class<Employee>. The type parameter T of the makePair method matches Employee, and the compiler can infer that the method returns a Pair<Employee>.
Generic Type Information in the Virtual Machine
One of the notable features of Java generics is the erasure of generic types in the virtual machine. Perhaps surprisingly, the erased classes still retain some faint memory of their generic origin. For example, the raw Pair class knows that it originated from the generic class Pair<T>, even though an object of type
Pair can’t tell whether it was constructed as a
Pair<String> or Pair<Employee>.
Similarly, consider a method public static Comparable min(Comparable[] a) that is the erasure of a generic method
public static <T extends Comparable<? super T>> T min(T[] a)
You can use the reflection API enhancements of Java SE 5.0 to determine that The generic method has a type parameter called T;
The type parameter has a subtype bound that is itself a generic type; The bounding type has a wildcard parameter;
The wildcard parameter has a supertype bound; and The generic method has a generic array parameter. In other words, you get to reconstruct everything about generic classes and methods that their
implementors declared.
java.lang.reflect.Method
• TypeVariable[] getTypeParameters()
gets the generic type variables if this method was declared as a generic method, or an array of length 0 otherwise.
• Type getGenericReturnType() 5.0
gets the generic return type with which this method was declared.
• Type[] getGenericParameterTypes() 5.0
gets the generic parameter types with which this method was declared. If the method has no parameters, an array of length 0 is returned.
ava.lang.reflect.TypeVariable
• String getName()
gets the name of this type variable.
• Type[] getBounds()
gets the subclass bounds of this type variable, or an array of length 0 if the variable is unbounded.
java.lang.reflect.WildcardType
• Type[] getLowerBounds()
gets the subclass (extends) bounds of this type variable, or an array of length 0 has no subclass bounds
• Type[] getUpperBounds()
gets the superclass (super) bounds of this type variable, or an array of length 0 has no superclass bounds.
java.lang.reflect.GenericArrayType Type getGenericComponentType()
gets the generic component type with which this array type was declared
5. What is Exception? Explain its mechanism. Exceptions
Encountering errors is unpleasant. If a user loses all the work he or she did during a program session because of a programming mistake or some external circumstance, that user may forever turn away from your program. At the very least, you must
Notify the user of an error; Save all work; andAllow users to gracefully exit the program.
For exceptional situations, such as bad input data with the potential to bomb the program, Java uses a form of error trapping called, naturally enough, exception handling.
Dealing with Errors
If an operation cannot be completed because of an error, the program ought to either Return to a safe state and enable the user to execute other commands; or
Allow the user to save all work and terminate the program gracefully
What sorts of problems do you need to consider
User input errors
|
Physical limitations.
Exception hierarchy in Java
How to Throw an Exception
Find an appropriate exception class. Make an object of that class.
Throw it.
Once a method throws an exception, the method does not return to its caller. This means that you do not have to worry about cooking up a default return value or an error code
Catching Exceptions
To catch an exception, you set up a try/catch block. The simplest form of the try block is as follows:
try
{
code more code more code
}
catch (ExceptionType e)
{
handler for this type
}
If any of the code inside the try block throws an exception of the class specified in the catch clause, then
The program skips the remainder of the code in the try block. The program executes the handler code inside the catch clause. Stack Trace Elements
A stack trace is a listing of all pending method calls at a particular point in the execution
of a program. You have almost certainly seen stack trace listings— they are displayed whenever a Java program terminates with an uncaught exception.
Before Java SE 1.4, you could access the text description of a stack trace by calling the printStackTrace method of the Throwable class.
Now you can call the getStackTrace method to get an array of StackTraceElement objects that you can analyze in your program.
For example:
Throwable t = new Throwable(); StackTraceElement[] frames = t.getStackTrace(); for
(StackTraceElement frame : frames)
analyze frame
The StackTraceElement class has methods to obtain the file name and line number, as well as the class and method name, of the executing line of code. The toString method yields aformatted string
containing all of this information.
6. Explain about Assertion and Logging. Assertions
Assertions are a commonly used idiom for defensive programming. Suppose you are convinced that a
particular property is fulfilled, and you rely on that property in your code. For example, you may be computing double y = Math.sqrt(x);
You are certain that x is not negative. Perhaps it is the result of another computation that
can’t have a negative result, or it is a parameter of a method that requires its callers to supply only positive inputs. Still, you want to double-check rather than having confusing “not a number” floating- point values creep into your computation. You could, of course, throw an exception:
if (x < 0) throw new IllegalArgumentException("x < 0");
But this code stays in the program, even after testing is complete. If you have lots of checks of this kind, the program runs quite a bit slower than it should.
The assertion mechanism allows you to put in checks during testing and to have them automatically removed in the production code.
As of Java SE 1.4, the Java language has a keyword assert. There are two forms:
assert condition;
assert condition : expression;
Both statements evaluate the condition and throw an AssertionError if it is false. In the second statement, the expression is passed to the constructor of the AssertionError object and
turned into a message string.
Assertion Enabling and Disabling
By default, assertions are disabled. You enable them by running the program with the - enableassertions or -ea option:
java -enableassertionsMyApp
Using Assertions for Parameter Checking
The Java language gives you three mechanisms to deal with system failures: Throwing an exception
Logging
Using assertions
When should you choose assertions? Keep these points in mind:
Assertion failures are intended to be fatal, unrecoverable errors.
Assertion checks are turned on only during development and testing. Using Assertions for
Documenting Assumptions
Many programmers use comments to document their underlying assumptions. Consider this example from http://java.sun.com/javase/6/docs/technotes/guides/language/assert.html: if (i % 3 == 0)
. . .
else if (i % 3 == 1)
. . .
else // (i % 3 == 2)
. . .
In this case, it makes a lot of sense to use an assertion instead. if (i % 3 == 0)
. . .
else if (i % 3 == 1)
. . . else
{
asserti % 3 == 2;
. . .
}
What are the possible values of i % 3? If i is positive, the remainders must be 0, 1,or 2. If iis negative, then the remainders can be −1 or −2. Thus, the real assumption is that iis not negative.
A better assertion would be asserti>= 0; // before the if statement.
LOGGING
Every Java programmer is familiar with the process of inserting calls to System.out.println into troublesome code to gain insight into program behavior. Of course, once you have figured
out the cause of trouble, you remove the print statements, only to put them back in when the next problem surfaces. The logging API is designed to overcome this problem.
Here are the principal advantages of the API:
It is easy to suppress all log records or just those below a certain level, and just as easy to turn them back on.
Suppressed logs are very cheap, so that there is only a minimal penalty for leaving the logging code in your application.
Log records can be directed to different handlers, for display in the console, for storage in a file, and so on.
+Both loggers and handlers can filter records. Filters discard boring log entries, using any criteria supplied by the filter implementor.
Log records can be formatted in different ways, for example, in plain text or XML.
Applications can use multiple loggers, with hierarchical names such as com.mycompany.myapp, similar to package names.
By default, the logging configuration is controlled by a configuration file. Applications can replace this mechanism if desired
Basic Logging
Let’s get started with the simplest possible case. The logging system manages a default loggerLogger.global that you can use instead of System.out. Use the info method to log an information message:
Logger.global.info("File->Open menu item selected"); By default, the record is printed like this: May 10, 2004 10:12:15 PM LoggingImageViewerfileOpen INFO: File->Open menu item selected
(Note that the time and the names of the calling class and method are automatically included.) But if you call Logger.global.setLevel(Level.OFF);
at an appropriate place (such as the beginning of main), then all logging is suppressed. Advanced
Logging
Now that you have seen “logging for dummies,” let’s go on to industrial-strength logging. In a professional application, you wouldn’t want to log all records to a single global
logger. Instead, you can define your own loggers. When you request a logger with a given name for the first time, it is created.
Logger myLogger = Logger.getLogger("com.mycompany.myapp"); There are seven logging levels:
SEVERE WARNING INFO CONFIG FINE FINER FINEST
By default, the top three levels are actually logged. You can set a different level, for example, logger.setLevel(Level.FINE);
Now all levels of FINE and higher are logged. You can also use Level.ALL to turn on logging for all levels or Level.OFF to turn all logging off.
There are logging methods for all levels, such as logger.warning(message); logger.fine(message);
and so on. Alternatively, you can use the log method and supply the level, such as logger.log(Level.FINE, message);
UNIT-V CONCURRENT PROGRAMMING
1. What is Multithreading? Multithreading
Multithreaded programs extend the idea of multitasking by taking it one level lower: individual programs will appear to do multiple tasks at the same time. Each task is usually called a thread— which is short for thread of control. Programs that can run more than one thread at once are said to be multithreaded Using Threads to Give Other Tasks a Chance
Here is a simple procedure for running a task in a separate thread:
1. Place the code for the task into the run method of a class that implements the Runnable interface. That interface is very simple, with a single method:
public interface Runnable
{
void run();
}
You simply implement a class, like this: classMyRunnable implements Runnable
{
public void run()
{
task code
}
}
Construct an object of your class: Runnable r = new MyRunnable(); Construct a Thread object from the Runnable: Thread t = new Thread(r); Start the thread:
t.start();
To make our bouncing-ball program into a separate thread, we need only implement a class
BallRunnable and place the code for the animation inside the run method, as in the following code:
classBallRunnable implements Runnable
{
. . .
public void run()
{
try
{
for (inti = 1; i<= STEPS; i++)
{ ball.move(component.getBounds()); component.repaint(); Thread.sleep(DELAY);
}
}
catch (InterruptedException exception)
{
}
}
. . .
}
Again, we need to catch an InterruptedException that the sleep method threatens to throw. We discuss this exception in the next section. Typically, interruption is used to request that a thread terminates. Accordingly, our run method exits when an InterruptedException occurs
Thread(Runnable target)
constructs a new thread that calls the run() method of the specified target. void start()
starts this thread, causing the run() method to be called. This method will return immediately. The new thread runs concurrently.
void run()
calls the run method of the associated Runnable. void run()
must be overriden and supplied with instructions for the task that you want to have executed.
2. Explain the Thread Concepts. Interrupting Threads
A thread terminates when its run method returns, by executing a return statement, after executing the last statement in the method body, or if an exception occurs that is not
caught in the method. There is a way to force a thread to terminate. However, the interrupt method can be used to request termination of a thread.
To find out whether the interrupted status was set, first call the static Thread.currentThread method to get the current thread and then call the isInterrupted method:
while (!Thread.currentThread().isInterrupted() && more work to do)
{
do more work
}
The interrupted thread can decide how to react to the interruption. Some threads are so important that they should handle the exception and continue. But quite commonly, a thread will simply want to interpret an interruption as a request for termination. The run method
of such a thread has the following form: public void run()
{
try
{
. . .
while (!Thread.currentThread().isInterrupted() && more work to do)
{
do more work
}
}
catch(InterruptedException e)
{
// thread was interrupted during sleep or wait
}
finally
{
cleanup, if required}
// exiting the run method terminates the thread
}
The isInterrupted check is neither necessary nor useful if you call the sleep method after every work iteration. If you call the sleep method when the interrupted status is set, it doesn’t sleep. Instead, it clears thestatus (!) and throws an InterruptedException. Therefore, if your loop calls sleep, don’tcheck the interrupted status. Instead, catch the InterruptedException, like this:
public void run()
{
try
{
. . .
while (more work to do)
{
do more work Thread.sleep(delay);
}
}
{
// thread was interrupted during sleep } finally
{
cleanup, if required
}
// exiting the run method terminates the thread
}
Thread States
Threads can be in one of six states: New
Runnable
Blocked
Waiting
Timed waiting
Terminated
New Threads
When you create a thread with the new operator—for example, new Thread(r)—the thread is not yet running
Runnable Threads
Once you invoke the start method, the thread is in the runnable state. A runnable thread may or may not actually be running
Blocked and Waiting Threads
When a thread is blocked or waiting, it is temporarily inactive. It doesn’t execute any code and it consumes minimal resources
Terminated Threads
A thread is terminated for one of two reasons:
It dies a natural death because the run method exits normally.
It dies abruptly because an uncaught exception terminates the run method
API
• void join()
waits for the specified thread to terminate.
• void join(long millis)
waits for the specified thread to die or for the specified number of milliseconds to pass.
• Thread.StategetState() 5.0
gets the state of this thread; one of NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, or TERMINATED.
• void stop()
stops the thread. This method is deprecated.
• void suspend()
suspends this thread’s execution. This method is deprecated.
• void resume()
resumes this thread. This method is only valid after suspend() has been invoked.
Thread Properties
Thread Priorities
In the Java programming language, every thread has a priority. voidsetPriority(intnewPriority)
sets the priority of this thread. The priority must be between Thread.MIN_PRIORITY and
Thread.MAX_PRIORITY. Use Thread.NORM_PRIORITY for normal priority.
• staticint MIN_PRIORITY
is the minimum priority that a Thread can have. The minimum priority value is 1.
• staticint NORM_PRIORITY
is the default priority of a Thread. The default priority is 5.
• staticint MAX_PRIORITY
is the maximum priority that a Thread can have. The maximum priority value is 10.
• static void yield()
causes the currently executing thread to yield. If there are other runnable threads with a priority at least as high as the priority of this thread, they will be scheduled next. Note that this is a static method
Daemon Threads
You can turn a thread into a daemon thread by calling t.setDaemon(true);
There is nothing demonic about such a thread. A daemon is simply a thread that has no other role in life than to serve others. Examples are timer threads that send regular “timer ticks” to other threads or threads that clean up stale cache entries
Handlers for Uncaught Exceptions
The ThreadGroup class implements the Thread.UncaughtExceptionHandler interface. Its uncaught- Exception method takes the following action:
If the thread group has a parent, then the uncaughtException method of the parent group is called. Otherwise, if the Thread.getDefaultExceptionHandler method returns a non-null handler, it is called. Otherwise, if the Throwable is an instance of ThreadDeath, nothing happens.
Otherwise, the name of the thread and the stack trace of the Throwable are printed on System.err voiduncaughtException(Thread t, Throwable e)
defined to log a custom report when a thread is terminated with an uncaught exception
Parameters:
The thread that was terminated due to an uncaught exception
The uncaught exception object
3. Explain the Synchronization Concept
Synchronization
In most practical multithreaded applications, two or more threads need to share access to the same data. What happens if two threads have access to the same object and each calls a method that modifies the state of the object? As you might imagine, the threads can step on each other’s toes. Depending on the order in which the data were accessed, corrupted objects can result. Such a situation is often called a race condition
An Example of a Race Condition
To avoid corruption of shared data by multiple threads, you must learn how to synchronize the access. In this section, you’ll see what happens if you do not use synchronization.
In the next section, you’ll see how to synchronize data access., we simulate a bank with a number of accounts. We randomly generate transactions that move money between these accounts. Each account has one thread. Each transaction moves a random amount of money from the account serviced by the thread to another random account. The simulation code is straightforward. We have the class Bank
with the method transfer.
This method transfers some amount of money from one account to another. (We don’t yet worry about negative account balances.) Here is the code for the transfer method of the Bank class.
public void transfer(int from, int to, double amount)
// CAUTION: unsafe when called from multiple threads
{
System.out.print(Thread.currentThread()); accounts[from] -= amount; System.out.printf(" %10.2f from %d to %d", amount, from, to);
accounts[to] += amount;
System.out.printf(" Total Balance: %10.2f%n", getTotalBalance());
}
Here is the code for the TransferRunnable class. Its run method keeps moving money out of a fixed bank account. In each iteration, the run method picks a random target account
and a random amount, calls transfer on the bank object, and then sleeps. classTransferRunnable implements Runnable
{
. . .
public void run()
{
try
{
inttoAccount = (int) (bank.size() * Math.random());
double amount = maxAmount * Math.random(); bank.transfer(fromAccount, toAccount, amount); Thread.sleep((int) (DELAY * Math.random()));
}
catch(InterruptedException e) {}
}
}
When this simulation runs, we do not know how much money is in any one bank account at any time. But we do know that the total amount of money in all the accounts should remain unchanged because all we do is move money from one account to another
The Race Condition Explained
In the previous section, we ran a program in which several threads updated bank account balances. After a while, errors crept in and some amount of money was either lost or spontaneously created. This problem occurs when two threads are simultaneously trying to update an account. Suppose two threads simultaneously
carry out the instruction accounts[to] += amount;
The problem is that these are not atomic operations. The instruction might be processed as follows: Load accounts[to] into a register.
Add amount.
Move the result back to accounts[to].
Now, suppose the first thread executes Steps 1 and 2, and then it is preempted. Suppose the second thread awakens and updates the same entry in the account array.
Then, the first thread awakens and completes its Step 3.
Lock Objects
Starting with Java SE 5.0, there are two mechanisms for protecting a code block from concurrent access. The Java language provides a synchronized keyword for this
purpose, and Java SE 5.0 introduced the ReentrantLock class. The synchronized keyword automatically provides a lock as well as an associated “condition,” which makes it powerful and convenient for most cases that require explicit locking. However, we believe that it is easier to understand the synchronized keyword after you have seen locks and conditions in isolation
Read/Write Locks
The java.util.concurrent.locks package defines two lock classes, the ReentrantLock that we already
discussed and the ReentrantReadWriteLock class. The latter is useful when there are many threads that read from a data structure and fewer threads that modify it. In that situation, it makes sense to allow shared access for the readers. Of course, a writer must still have exclusive access.
Here are the steps that are necessary to use read/write locks:
1. Construct a ReentrantReadWriteLock object:privateReentrantReadWriteLockrwl = new
ReentrantReadWriteLock(); 2. Extract read and write locks:
private Lock readLock = rwl.readLock(); private Lock writeLock = rwl.writeLock();
3.Use the read lock in all accessors: public double getTotalBalance()
{
readLock.lock(); try { . . . }
finally { readLock.unlock(); }
}
4.Use the write lock in all mutators: public void transfer(. . .)
{
try { . . . }
finally { writeLock.unlock(); }
}
Condition Objects
Often, a thread enters a critical section, only to discover that it can’t proceed until a condition is fulfilled. You use a condition object to manage threads that have acquired
a lock but cannot do useful work.
4. What is Thread Safe Collection and Why it is used? Thread-Safe Collections
If multiple threads concurrently modify a data structure such as a hash table, then it is easily possible to damage the data structure. For example, one thread may begin to insert a new element. Suppose it is
preempted while it is in the middle of rerouting the links between the hash table’s buckets.
If another thread starts traversing the same list, it may follow invalid links and create havoc, perhaps throwing exceptions or being trapped in an infinite loop.You can protect a shared data structure by supplying a lock, but it is usually easier to choose a thread-safe implementation instead.
The blocking queues that we discussed in the preceding section are, of course, thread-safe collections. In the following sections, we discuss the other thread-safe collections that the Java library provides.
Efficient Maps, Sets, and Queues
The java.util.concurrent package supplies efficient implementations for maps, sorted sets, and queues: ConcurrentHashMap, ConcurrentSkipListMap, ConcurrentSkipListSet, and ConcurrentLinkedQueue.
These collections use sophisticated algorithms that minimize contention by allowing concurrent access to different parts of the data structure.
Unlike in most collections, the size method does not necessarily operate in constant time. Determining the current size of one of these collections usually requires traversal. The collections return weakly consistent iterators. That means that the iterators may or may not reflect all modifications that are made after they were constructed, but they will not return a value twice and they will not throw a ConcurrentModificationException.
Older Thread-Safe Collections
Ever since the initial release of Java, the Vector and Hashtable classes provided thread-safe implementations of a dynamic array and a hash table. In Java SE 1.2, these classes were
declared obsolete and replaced by the ArrayList and HashMap classes. Those classes are not thread- safe.
Instead, a different mechanism is supplied in the collections library. Any collection class can be made thread-safe by means of a synchronization wrapper:
List<E>synchArrayList = Collections.synchronizedList(new ArrayList<E>());
Map<K, V>synchHashMap = Collections.synchronizedMap(new HashMap<K, V>());
The methods of the resulting collections are protected by a lock, providing thread-safe access.
Executors
The various Executor implementations provide different execution policies to be set while executing the tasks. For example, the ThreadPool supports the following policies:
newFixedThreadPool: Creates threads as tasks are submitted, up to the maximum pool size, and then attempts to keep the pool size constant.
newCachedThreadPool: Can add new threads when demand increases, no bounds on the size of the pool.
newSingleThreadExecutor: Single worker thread to process tasks, Guarantees order of execution based on the queue policy (FIFO, LIFO, priority order).
newScheduledThreadPool: Fixed-size, supports delayed and periodic task execution.
Thread Pools
The pool will run the submitted task at its earliest convenience. When you call submit, you get back a
Future object that you can use to query the state of the task.
The first submit method returns an odd-looking Future<?>. You can use such an object to callisDone, cancel, or isCancelled. But the get method simply returns null upon completion.
The second version of submit also submits a Runnable, and the get method of the Future returns the given result object upon completion.
The third version submits a Callable, and the returned Future gets the result of the computation when it is ready.
Scheduled Execution
The ScheduledExecutorService interface has methods for scheduled or repeated execution of tasks. ScheduledExecutorServicenewScheduledThreadPool(int threads)
returns a thread pool that uses the given number of threads to schedule tasks.
• ScheduledExecutorServicenewSingleThreadScheduledExecutor()
returns an executor that schedules tasks in a single thread. ScheduledFuture<V> schedule(Callable<V> task, long time, TimeUnit unit) zcheduledFuture<?> schedule(Runnable task, long time, TimeUnit unit) schedules the given task after the given time has elapsed.
ScheduledFuture<?>scheduleAtFixedRate(Runnable task, long initialDelay, long period,TimeUnit unit) schedules the given task to run periodially, every period units, after the initial
delay has elapsed.
ScheduledFuture<?>scheduleWithFixedDelay(Runnable task, long initialDelay, long delay, TimeUnit unit) schedules the given task to run periodially, with delay units between completion of one
invocation and the start of the next, after the initial delay has elapsed.
5. What is Event-Driven Programming and explain its usage.
Event-Driven Programming
In computer programming, event-driven programming or event-based programming is a programming paradigm in which the flow of the program is determined by events—i.e., sensor outputs or user actions (mouse clicks, key presses) or messages from other programs or thread.
In Java
User-interface objects (such as buttons, list boxes, menus, etc.) keep an internal list of "listeners".
These listeners are notified (that is, the listener’s methods are called) when the user-interface object generates an event.
To add listeners to the list you make a call like yellowButton.addActionListener(...). What you put in the place of the ... must be an object implementing the ActionListener interface, so it will have methods
capable of processing the events generated. Of course, if the interface is not a button or menu,
ActionListener may not be the appropriate interface—there are eleven listener interfaces.
How to get an object implementing a listener interface
1.You could, for example, make your panel class implement any listener interface by the method used for
MouseMotionListener in DragTest.java: classMousePanel extends JPanel implementsMouseMotionListener
{ ...//implement mouseClicked and mouseDragged
2.You can use an anonymous inner class as illustrated in all our programs for the WindowListener
interface, or by the treatment of MouseListener in DragTest.java
...addMouseListener(new MouseAdapter() { public void mousePressed(
MouseEventevt)
{ ...
3.You can create an Action object as illustrated in SeparateGUITest.java: classColorAction extends
AbstractAction
{ publicColoraction(...
{ putValue(Action.NAME,...)
...
// construct the action from given parameters
}
public void actionPerformed(ActionEventevt)
}
blueAction = new ColorAction("blue", ...); and add this object as a listener:
blueButton.addActionListener(blueAction);
No comments:
Post a Comment