You are on page 1of 93

String and StringBuffer

String
String is a class in "java.lang" built-in package. String is declared as final class String implements marker interfaces "Serializable", "Comparable", "CharSequence". The compiler makes sure that each String constant actually results in a String object. String object can be created in two ways

1. Using 'new' Operator Syntax: String s=new String("javasree"); 2. without using 'new' operator Syntax: String s="javasree";

Constructor List
String() : String(String) : String(char[]) : String(char[], int, int) : String(byte[], int, int, int) : String(byte[], int) : Constructs a new empty String. Constructs a new String that is a copy of the specified String. Constructs a new String whose initial value is the specified array of characters. Constructs a new String whose initial value is the specified sub array of characters. Constructs a new String whose initial value is the specified sub array of bytes. Constructs a new String whose initial value is the specified array of bytes.

Strings are special, in that they are the only object with an overloaded operator. When you use '+' with at least one String argument, both arguments have String conversion performed on them, and another String (not guaranteed to be unique) results. String is special-cased when doing data serialization - rather than listing the fields of this class, a String object is converted to a string literal in the object stream. String objects are immutable (ie) once string object is created it cannot be changed but we can change string reference variable. Because String objects are immutable they can be shared. Hash code of Strings will be calculated as follows: Ex: String s="abcde" Hash code of 's' is calculated = a*31^4+b*31^3+c*31^2+d*31+e

When a string is concatenated, every time a new string object will be created as shown below : Ex: String st= "javasree"; st=st + ".com"; The last statement in above example a new String object "javasree.com" will be created and assigned to reference variable 'st'. Now st point to "javasree.com" not "javasree" This always consumes lot of memory each time a new object is created. To solve this problem sun has provided concept called "String constant Pooling" or "String object Pooling"

String Constant Pool


String Constant Pool is some memory which contains String constants (or) a Pool of String Constants Ex: case (I) String s1=new String("abc"); String s2=new String("abc"); case (II) String s="abc"; Sting st="abc"

Uses of String Constant Pooling Mechanism

Under case(I) For the objects created for string with 'new' operator, JVM won't verify pool, directly it will create a new string object. String Constant pool is not eligible for Garbage Collection. Under case(II) For objects created for string without 'new' operator, first JVM will verify pool to check whether the object is available in the pool or not. If available, that object reference will be assigned to reference variable. It won't create a new object. JVM will maintain String Constant Pool, Pool list until the system is turned off. Example illustrating difference between "==" & "equals()": class St { public static void main(String as[]) { String s1=new String("abc"); String s2=new String("abc"); if(s1==s2) System.out.println("equal"); else System.out.println("equal"); if(s1.equals(s2)) System.out.println("equal"); else System.out.println("equal"); } } Output: not equal equal

String Buffer
Introduction : StringBuffer is a class in "java.lang" build-in package. StringBuffer is declared as final class StringBuffer implements marker interfaces "Serializable", "CharSequence". A string buffer implements a mutable sequence of characters. String buffers are safe for use by multiple threads. The methods are synchronized where necessary so that all the operations on any particular instance behave as if they occur in some serial order that is consistent with the order of the method calls made by each of the individual threads involved. Every string buffer has a capacity. Every new String Buffer object created default 2 bytes of length will be allocated as capacity of the object. As long as the length of the character sequence contained in the string buffer does not exceed the capacity, it is not necessary to allocate a new internal buffer array. If the internal buffer overflows, it is automatically made larger as follows: New capacity=old capacity * 2

Constructor List
public StringBuffer(); public StringBuffer(int length); public StringBuffer(String str);

Example using String Buffers


class Sb { public static void main(String as[]) { StringBuffer sd1=new StringBuffer(); StringBuffer sd2=new StringBuffer("sri"); System.out.println(sd1.length()); System.out.println(sd1.capacity()); System.out.println(sd2.capacity()); System.out.println(sd2.length()); } } Output : 0, 16, 19, 3.

Differences between String & StringBuffer :


String 1.String objects are immutable 2.String objects don't have default capacity 3.Implemented interfaces : Serializable, Comparable, Char Sequence. 4. String is special-cased when doing data serialization StringBuffer 1.StringBuffer objects are mutable 2.Every string buffer has a default capacity 3.Implemnted interfaces : Serializable, Char Sequence 4.String buffers are safe for use by multiple threads.

INNER CLASSES
A class that is declared and defined inside some other class is called an Inner class. Sometimes it is also called a nested class. In Java it is a feature added since jdk1.1. The inner classes give additional functionality to the program and make it clear. Let us look at the basic construction of the inner class. Like variables and methods, we can write classes also inside a class or interface. We have four types of inner classes. Non-static Inner classes Static Inner classes Method-Local Inner classes Anonymous Inner classes Non Static Inner Classes: class Outer { int x; void m1() { System.out.println(x); Inner i=new Inner(); i.m2(); } class Inner { int y; void m2() { System.out.println(x); System.out.println(y); } } }

class InnerClassDemo { public static void main(String arg[]) { Outer out=new Outer(); out.m1(); } } Outer class members can be accessed inside the inner class directly. Inner class members can not be accessed inside the outer class directly but we can access by creating object of inner class. The scope of non-static inner class is the outer class where it is defined. Inner classes have access to their enclosing class?s scope. The accessibility of the members of the enclosing class is crucial and very useful. The access to enclosing class?s scope is possible because the inner class actually has a hidden reference to the outer class this reference. Static Inner Classes: Unlike an outer class an inner class may be private, static or abstract. Marking an Inner class static has some interesting effects with regards to accessing the fields of the enclosing class. The effect of marking it as static means there is only one instance of any variable no matter how many instances of the outer class are created. In this situation how could the static inner class know which variables to access of its non-static outer class? The answer is that it could not know, and thus a static inner class cannot access instance variables of its enclosing class. The methods of a static inner class can of course access any static fields of its enclosing class, as their will only be one instance of any of those fields. class Outer { static int x; void m1() { System.out.println(x); Inner i=new Inner(); i.m2(); }

static class Inner { int y; void m2() { System.out.println(x); System.out.println(y); } } } class InnerClassDemo { public static void main(String arg[]) { Outer out=new Outer(); out.m1(); Outer.Inner outin=out.new Inner(); outin.m2(); } } Method-Local Inner Classes When you define a class inside a method that is called as method-local inner class. The scope of this class is within the method itself where it is defined. Below is a example of the method-local inner classes. class InnerDemo { void m1() { System.out.println(?Hello?); class Hello { void m2() { System.out.println(?I am in method-local inner class?); }

} Hello h=new Hello(); h.m2(); } } Anonymous Inner Classes A class without a name defined inside a method is called an Anonymous Class. Anonymous Classes are defined in the place they are constructed. In certain situations an inner class need to be defined without name. This type of inner class declarations is called anonymous inner classes. You will see this type of inner class declaration in GUI event handling mechanisms of Java. Declaring of Anonymous class: Anonymous inner classes are defined by coke in a block following the use of new operator and an associated constructor. new may be used with the name of a class or the name of an interface. If an anonymous inner class is defined in a block following the application of new on class X then it defines a class that extends class X. If an anonymous inner class is defined in a block following the application of new to interface Y then it defines a class which implements interface Y. interface Animal { void eat(); void sleep(); } class AIDemo { Animal ani=new Animal(); { void eat() { System.out.println(?eating?); } void sleep() { System.out.println(?sleeping?);

} } } *Important Tips on Anonymous Following are a few important points that should be kept in mind while writing Anonymous classes: Anonymous inner class cannot have constructor. The declaration and instantiation of anonymous inner classes should be done at the same place. An anonymous class can either explicitly extend a class or explicitly implement an interface, but you cannot do both extending and implementing of an interface. An anonymous class cannot have a constructor. Since you do not specify a name for the class, you cannot use that name to specify a constructor.

PACKAGES
Packages are java's way of grouping a variety of classes and/or interfaces together. The grouping is usually done according to functionality. In fact, packages act as "containers" for classes. By organizing our classes into packages we achieve the following benefits. 1. The classes contained in the packages of other programs can be easily reused. 2. In packages, classes can be unique compared with classes in other packages. That is, two classes in two different packages can have same name. They may be referred by their fully qualified name, comprising the package name and the class name. 3. Packages provide a way to "hide" classes thus preventing other programs or packages from accessing classes that are meant for internal use only. 4. Packages also provide a way for separating "design" from "coding". First we can design classes and decide their relationships, and then we can implement the java code needed for the methods. It is possible to change the implementation of any method without affecting the rest of the design. ? Package is a collection of classes,which is a folder to store ".class" files.Sun has given some packages which are built in packages. Java API Packages: Java API provides a large number of classes grouped into different package according to functionality. Most of the time we use the packages available with the java API. The below figure shows the functional breakdown of packages that are frequently used in the programs.

Frequently used API packages

Java System Packages and their Classes:


Package.name Contents Java. lang Java.util Java.io Java.net Java.awt Java. applet Language support classes. These are classes that java compiler itself uses and therefore they are automatically imported. They include classes for primitive types, strings, math functions, threads and exceptions./ Language utility classes such as vectors, hash tables, random numbers, date, etc. Input/Output support classes. They provide facilities for the input and output of data. Classes for networking. They include classes for communicating with local computers as well as with internet servers. Set of classes for implementing graphical user interface. They include classes for windows, buttons, lists, menus and so on. Classes for creating and implementing applets.

Creating Packages: We must declare the name of the package using the package keyword followed by a package name. This must be the first statement in a java source file. Then we define a classjust as we normally define a class. Example:package firstPackage; declaration public class FirstClass definition { ?????? ?????? ?????? } Here the package name is firstPackage. Naming Conventions: Packages can be named using the standard java naming rules. By convention, however, packages begin with lowercase letters. This makes it easy for users to distinguish package names from class names when looking at an explicit reference to a class. We know that all class names, again by convention, begin with an uppercase letter. For example, look at the following statement: Double y= java.lang.Math.sqrt(x); This statement uses a fully qualified class name Math to invoke the method sqrt(). Note that methods begin with lowercase letters. Accessing a Package: It will be recalled that we have discussed earlier that a java system package can be accessed either using a fully qualified class name or using a shortcut approach through the import statement. We use the import statement //package //class

when there are many references to a particular package or the package name is too long and unwieldy. The same approaches can be used to access the user-defined packages as well. The import statement can be used to search a list of packages for a particular class. The general form of import statement for searching a class is a follows: import firstpackage.secondpackage.MyClass; After defining this statement, all the members of the class My Class can be directly accessed using the class name or its objects (as the case may be) directly without using the package name: We can also use another approach as follows: import packagename.*; Here, package name may denote a single package or a hierarchy of packages as mentioned earlier. The star (*) indicates that compiler should search this entire package hierarchy when it encounters a class name. This implies that we can access all classes contained in the above package directly. Using a Package: Let us now consider some simple programs that will use classes from other packages. The listing below shows a package named package1 containing a single class Package package1; public class ClassA { public void display() { System.out.println("Class A"); } }

This source file should be named classA. Java and stored in the sobdirectory package1 as stated earlier. Now compile this jave file. The resultant classA.class will be stored in the same subdirectory. Importing classes from other packages: import package1.ClassA; import package2.*; Class PackageTest2 { public static void main(String as[]) { ClassA objectA= new ClassA(); ClassB objectB= new ClassB(); objectA.displayA(); objectA.displayB(); } } Compiling the packages: Compilation of the PackageTest2 is shown below.

Javac -d . PackageTest2.java; ? Here -d indicates folders will be created with the same pattern as declared in the package . ? "." Indicates compiled .class file will be stored within the same drive. ? We can specify the path instead of '.' Running the package: Running of the package "Package package1.PackageTest2" shown below. ? Java package1.PackageTest2;

Access specifiers (or) Visibility modifiers


We have four types of Access specifiers : 1. private 2. default 3. protected 4. public Private members can be accessed within the class only. Default members can be accessed within the class, subclass and non-subclass of within the package. Protected members can be accessed within the class, inside subclass and non-subclass of same package and subclasses of different packages. Public members can be accessed anywhere. Order of access specifiers :

The table given below will make the concept of access modifiers more clear : Access Modifiers Accessible inside the class Accessible within the subclass inside theSame package. Accessible outside the package Accessible within the subclass outside the package default yes yes no no Private yes no no no Protected yes yes no yes Public yes yes yes yes

Method Overriding : Implementing the super class method is a subclass with the same-method signature, return type and access specifiers is called method overriding.

Rules for method overriding : Superclass method signature must be same as subclass method signature. Subclass method 'return type' must be same as superclass method return type. When superclass method has the access specifier then subclass method must have same access specifier (or) any other which has highest privileges than super class specifier.

When super class method is throwing method level exception, in subclass the following is legal : 1. We can omit the method level exception. 2. We can throw the same exception. 3. We can throw any other exception which is subclass to superclass method exception. 4. Don't throw superclass of superclass method exception. Note : private methods can be overridden. static methods can be overridden. static methods can't be overridden as non-static methods. We can't override main method with string array as arguments.

Java Language
Java Character set : Alphabets (A---Z),(a---z) Digits (0--------9) Special Symbols (+,-,/,{,},[,],*?..etc) Identifiers : Identifiers are the name which you can form using character and character set we can use identifiers for following : Variable name Method name Class name Interface name Package name Constants Following are the rules we need to follow to form legal identifiers : a) We have to use the characters from java character set only. b) First character must be alphabets.Digits & special symbols are not allowed except "_" and "$" c) Key words cannot be used as identifiers. d) Identifiers cannot be keywords. Keywords : Keywords are the words which have predefined meaning. You can not change the meaning of the keywords it is called as reserve words. We have 49 key words. Access Specifiers Key words : private public protected Variable, Method & Class keywords : class interface static abstract final volatile transient native strictfp instanceOf

new synchronized Data types : int float char double long short byte boolean Package : package import Reference variable key words : this super Control statement keywords : if else for while do switch break continue default case Exception handling key words : try catch throw throws finally assert Depricated list key words : goto const MISC : implements

extends void return

DATA TYPES
We have 8 primitive data types in java : No 1. 2. 3. 4. 5. 6. 7. 8. Data types byte short int long float double char boolean Size in byte 1 2 4 8 4 8 2 not specified 0 0 0 0 0.0f 0.0d '\u0000' false Default value -128 to +127 -32,768 to +32,767 -2,147,483,648 to +2,147,483,647 -9,223,372,036,854,775,808 to +9,223,372,036,854,775,807 1.40129846432481707e-45 to 3.40282346638528860e+38 4.94065645841246544e-324d to 1.79769313486231570e+308d '\u0000' (or 0) to '\uffff' (or 65,535) not require Range

Note : byte, short, int, long, float & double are number types in Java. All the number's are signed i.e we can store both +ve & -ve values . For example, in integer 1 bit is signed bit & remaining 31 bits are data bits. Variables : Variable is a name which is given to memory location. (or) Variable is name which is used to access the data in the program. Declaration of variables : Data type var1, var2, var3???; Ex: int a,b,sum; float f,g; char c,d;

Before using the variable in the program, we should declare that first other wise it will give syntax error. The statement which you are using to declare the variable is called declaration statement. Initialization variables at declaration time: Data type var1=value1, var2=value2??..; Ex: int x= 10, y=20; Simple program : Class Hello {public static void main(string as[]) { System.out.println("welcome to Java@javasree.com"); }} Compiling java program: javac Hello.java Run java program: java Hello Class Vardemo { static int I; static short s; static byte b; static long l; static float f; static double d; static char ch; static boolean b; public static void main(String args[]) { int a=99; System.out.println(a); System.out.println(s); System.out.println(i); System.out.println(b); System.out.println(l); System.out.println(f); System.out.println(d); System.out.println(ch); System.out.println(b); }}

Syntax : find data type <identifier>=value; Ex: final int x=20; Constants are called final variables whose values cannot be changed.

Literals : Literal is nothing but a value .we have 4 types of literals : 1.Integer literal. 2.floating point literal. 3.character literal. 4.String literal. 1.Integer literal: Integer literal is nothing but collection of digits without a decimal point .We have 3 types of integer literal in JAVA : a)decimal Integer literal(o?..9). b)octal Integer literal(0?..7). c)Hexa decimal Integer literal(0?.9, A?.F, a?.f). 2.Floating point literal :It is collection of digits with decimal points(or) exponential notation Ex:12.56, 123e-7 3.character literal: single character which is enclosed between single quotation is called character literal. Ex: 'A','a','+' Character literals uses ASCII character set to store the values internally. i.e. every character which is enclosed between single quotation marks will be same as ASCII value. 4.String literal : one or more character enclosed between double quotation marks is called a String literal. Ex:"srinivas"; "ab+12999"; Operators 1.Arithmetic Operator(+,-,*,/,%) 2.Assignment Operator(=,+=,-=,*=,/=,%=) 3.Relational Operator (<,<=,>,>=,==,!=) 4.logical operator(--,++) 5.ternary operator(?:) 6.Bitwise Operator(>>,<<,&,|,!,^) 7.instanceOf operator 8.new operator Logical Operators : logical operators are used to combine two (or) more relational expressions. The result of relational expression is Boolean value and logical Expression also. The result of logical operator will be determined using following both tables.

Unary operators :
Ex: Postfix: prefix : int int int int int int x=16; a1=x++; a2=x++; a3=++x; a4=--x; a5=x--; a++ --a a-++a

Ternary operator : It is used to do some simple conditions. Syntax: var = (condition)? exp1:exp2; First condition will be evaluated ,if the condition is true value of exp1 will be assigned to var else exp2 value. Ex: max = (a>b)?a:b; Bitwise Operators : << left shift >> right shift & bit wise logical and | bit wise logical or ^ bitwise logical xor ~ bit wise logical not (negation) Bit wise operators operator on bits of given values.

Java Language

JAVA's encoding technique is 1's compliment. Left shift(<<) : Tthis operator shifts the bits of a given value to left with specified number of times Syntax : 16<<2 Right shift(>>) : This operator shifts the bits of a given value to right a specified number of times. Syntax : 16>>2
class BitWise{ public static void main(String as[]){ int a=16; System.out.println(a>>2); System.out.println(a<<2); System.out.println(a&2); System.out.println(a|2); System.out.println(a^2); } }

instanceOf operator : This operator is used to check whether the given object is object (or) instanceOf given class are not. new : This operator is used to allocate the memory for objects(i.e allocate the memory for instance variables in the class). Control Statements :
1.if-else 2.switch 3.while 4.do-while 5.for 6.continue 7.break

If-else :

Syntax : If(condition) { Statement 1; Statement 2; ............ Statement n;

} else { Statement 1; Statement 2; ............ } Statement n;

if Statement is used to select one particular block between two blocks based on the condition. first condition will be evaluated .if the condition is true. True block (if block) will be executed otherwise false block will be executed.
Ex : Write a program to find whether the given number is odd or even? class OddEven { public static void main(String as[]) { int a=Integer.parseInt(as[0]); if(a%2==0) { System.out.println("Even number"); } else { System.out.println("Odd number"); } } }

Switch :

Syntax: Switch(expression) { case val1:statement1;break; case val2:statement2;break; ............ ............ default:statement1; }

Switch statement is used to select one set of Statement's among multiple sets.Firsr the expression will be evaluated and that value will be compared against different values provides in different cases. If any case value matches with that value the statement which belongs to that case will be executed and control will be transferd to next statement of switch using break. When no case value found default case will be executed. All cases are executed first and then goto default .we can Place default any where. Ex: Write a program to accept the number .if a number is between 1 and 7 display the corresponding day other wise display invalid number?
class switch1

{ public static void main(String as[]) {

int n=Integer.parseInt(as[0]); switch(n) { case 1: System.out.println("Monday");break; case 2: System.out.println("tueday");break; ............. ............. case 7: System.out.println("sunday");break; default: System.out.println("invalid number"); }}

while : while statement is used to execute set of statement.For specified number of times firsr we need to initialize a variable. when while statement encountered condition will be evaluated. 1'st if condition true statement inside the loop will be executed.if condition false control comes out of the loop. do-while :
do { Increment (or) decrement; .......... .......... }while(condition);

for statement :
for(initialization;condition;increment/decrement) { .......... .......... }

First initialization will be executed and then condition will be evaluated .If the condition is true the statement inside the loop will be executed,after that increament/decrement will happen and then condition will be evaluated. if condition is true above thing will happen else control comes out of the loop.
Ex: Write a program to print the even number's from 1 to 100? class Demo { public static void main(String as[]) { for(int i=1;i<=100;i++) { If(i%2==0) System.out.println(i); } }}

Break statement : it is un conditional control statement which is used to transfer the control to end of the break (or)loop. while(condition) { ........ ........ Break; } while(condition) { ....... ....... continue; }

Continue statement : it is also condition control statement which is used to transfer the control to begining of the block(or)loop. Arrays : Collection of similar type is called as an Array. Arrays are object in JAVA.
Syntax: Data type array name[]=new data type[size]; (or) Data type Array name []; Array name =new Data type[sze]; int[9]; value of object in java is null. to construct/allocate object,memory. also called as Array of Arrays.

Ex: int a[]; a=new The default new is used 2-D arrays: 2-D array is

Ex : int x[][]=new int [3][3]; It will allocate reference variable 'x' which null. Int a[][]=new int [3][]; A[0]=new int[2]; A[1]=new int [3]; A[2]=new int[4];

When you are using index which is not available JVM throws.ArrayIndexOutOfBoundException
class ArrayDemo { public static void main(String as[]) { int x[]=new int[3]; int a[]=new int[][99,88]; int b[]=[10,20]; System.out.println(b.length); Int z[][]=new int [][]{10,20,30}; Int d[][]=new int[4][];

for(int i=0;i<d.length;i++) { System.out.println(d[i]); d[0]={10,20}; d[2]=new int[2]; for(int i=0;i<d.length;i++) { System.out.println(d[i]); } //d[6]=new int [3]; } }}

Type casting : converting one data type to another data type is called type casting. There are 2 types : 1.widening (or) implicit casting. 2.narrowing (or) explicit casting.
Ex : class Castdemo { public static void main(String as[]) { byte b=10; short s=20; int i=30; //float f=88.9;

float f1=88.9f; double d=99.9; long l=40; boolean bo=false; char ch='a'; b=i;//possible lose of precision ,narrowing error. B=(byte)I; i=s;//widening i=bo;//incompatable types i=(int)bo;//in compatable type l=ch; byte b1=10; byte b2=b1*2; byte b2=(byte)b1*2; } }

Garbage Collection
With respect to the internals of Java Virtual Machine (JVM) it is known that heap stores all the objects created while execution of a java program. Objects are created by using new, new array etc. instructions but these are never freed explicitly by the code. Garbage collection is the mechanism or process that automatically frees the memory occupied by the objects that are no longer referenced by the program. Garbage collector (gc) is a thread, which is running behind the scenes, which de-allocates memory of unused objects in the heap. JVM watches your heap memory when you are running out of memory it invokes gc which deallocates memory of unused objects in the heap. Garbage collector will be invoked by the JVM. As a programmer if you want to call the gc, it can be done by following code : System.gc(); Where system is a class in java.lang.package and gc() is a static method in System class. We cannot force the garbage collector i.e. when we call System.gc( ), JVM may or may not invoke garbage collector. JVM identifies unused objects with the following criteria: 1. Void x () { Hello e1=new Hello () e1.m1 (); e1.m2 (); ----------------------------}

When a reference variable reaches out of scope. Then object, which is referred by the particular reference variable is unused and is eligible for garbage collection. 2. void x () { Hello c1 = new Hello(); Hello c2 = new Hello(); c1=c2; c1.m1(); c2.m2(); }

When we assign one reference variable to another reference variable with equals operator, then object which is referred by a reference

variable left side to equals operator is unused and is eligible for garbage collector. 3. void x () { Hello c1= new Hello(); c1.display(); c1= null; }

When we assign a null to a reference variable is unused and eligible for garbage collection. When JVM invokes garbage collector, gc will try to reclaim the memory of unused objects. Sometimes some unused objects may refuse to reclaim the memory, because of those unused objects still holds some resources. So first we have to release the resource then only we can reclaim the memory from those objects. For this what JVM will do is: 1. It calls System.runFinalization () method before invoking the garbage collector. 2. System.runFinalization () it invokes the overridden finalize methods (programmers overridden finalize method) of existing object in the heap. For this as a programmer you have to implement the finalize method of the superclass.

Garbage Collection Advantages :


It helps ensure program integrity. The programmer is freed from deallocating memory in the programs. Garbage collection is an important part of java's security strategy. Java programmers are unable to accidentally or purposely crash the JVM by incorrectly freeing memory.

Garbage Collection Disadvantages :


It adds an overhead that can affect program performance. The java Virtual machine has to keep track of which objects are being referenced by the executing program, and finalize and free unreferenced objects on the fly. This activity will likely required more CPU time than would have been required if the program explicitly freed unnecessary memory.

Wrapper classes
Introduction :There may be many situations where you need to use the primitive datatypes as objects or viceversa. Java uses simple datatypes such as int, float,etc. These types are not part of object hierarchy. You may encounter situations where you will need to create object representation of these simpletypes. For example, if you want to store primitive datatypes along with other objects in an array.Inx collection framework we have a lot of collectionclasses like ArrayList,Vector,Hashtable,HashMap,etc,. To address this need, java provides classess that corresponds to each of the simple datatypes.These classes are called Wrapper classes. Java provides "Wrapper" to manipulate primitive data elements as objects.Each primitive datatype has a corresponding wrapper class.Theseclasses are as follows: Primitive datatype Wrapper class boolean byte char short int long float double Boolean Byte Char Short Integer Long Float Double

How to convert primitive to wrapper object?


There are two ways to do the above conversion:1. By passing the primitive as parameter to the corresponding wrapper class constructor.

2. a. First convert the primitive to string object. b. Now convert the above string object to corresponding wrapper object.
Example 1:Conversion of int a=10 (primitive) to wrapper object 1.Integer obj=new Integer(a); 2.String str =Integer.toString(a); Integer obj=Integer.valueOf(str);

How to convert wrapper object to primitive?


There are two ways to do the above conversion:1) By calling the xxxValue () method. 2. a. First convert the wrapper object to string object. b. Now convert the above string object to corresponding primitive.
Example 1:primitive Conversion of Integer object obj (in example1) to 1) int a= obj.intValue(); 2) String str =obj.toString(); int a = Integer.parseInt(str);

Some Conversions:How to convert String to primitive? Use parsexxx() method. How to convert primitive to String? Use toString(xxx); How to convert wrapper object to String? Use toString(); How to convert String to wrapper object? Use valueOf(); How to convert Not possible. boolean to other datatypes?

Note: In the above conversions "xxx" may be int, short, byte, float, double, long.

Overloading
Method Overloading : Writing more than one method with the same name by changing the parameters is called Method Overloading. Rules : 1. Method name must be same. 2. We must change the parameters as follows. Number of parameters. Order of parameters. Type of parameters. 3. Return type may be anything. Constructors : 1. Constructors are "special methods" whose name is same as class name. 2. Constructors doesn't have any return type even void also. 3. Constructors will be invoked by the JVM when you are creating object. 4. Constructors can be overloaded. 5. Constructors is used to initialize objects.
Example : class Hello { int a,b; Hello() { System.out.println("Iam a constructor"); a=88; b=99; } Void m1() { System.out.println ("Iam a method m1"); System.out.println ("a value is"+a); System.out.println ("b value is"+b); } } class Ex1 {

public static void main(String as[]) { Hello h= new Hello(); h.m1(); }

Output : Iam a constructor Iam a method m1 a value is 88 b value is99

Desc : Hello h=new Hello(); Memory will be allocated for a reference variable (h).

Memory will be allocated for instance variables of the class.

Execution of static blocks. Default constructor (constructor without arguments) will be invoked.

Object address will be assigned into reference variable 'h'.

Constructor Overloading : We can do the following by overloading the constructors : 1. I want to initialize different objects of a class with different set of values. 2. I want to provide different values dynamically when I'm creating the object. Note : JVM inserts default constructor when there is no other constructor. JVM doesn't insert default constructor when the class has overloaded constructors. this operator : This is a reference variable which contains object of current class. When you have same name for the local variables and instance variables, local variables hides the instance variables.This is called as shadowing. To refer the instance variable qualify the variable with "this". i.e. "this.a".

Different Types of Variables

Any variable which is declared by class is called reference variable. Default value of any reference variable is null. JVM allocates the memory for all variables with this new operator.

Difference between local variables and instance variables


Local variables 1. Variables declared inside the method are called as local variables. Instance variables 1. Variables declared inside the class and outside the method are called as Instance variables.

2. Scope of the local variables is within that 2. Scope of the instance variable is within method where it is declared the class(in all the methods). 3. JVM doesn't initialize local variables. We have to initialize the local variables explicitly. 4. Memory will be allocated for local variables when the method is invoked. 5. JVM allocates the memory for local variables in the stack frame. 3. JVM initializes the instance variables. 4. Memory will be allocated for instance variables when object is created. 5. JVM allocates the memory for instance variables in the heapframe.

Stack memory and Heap memory : JVM uses heap memory to allocated memory for instance variables and objects. Instance variables may be primitive variables or reference variables. JVM uses stack memory to construct the stack. JVM creates one stack for class. Stack will be divided into number of stack frames

based on the no. of methods available in that class. Memory will be allocated for local variables within the stack frame in which the corresponding method definition is available.

Blocks : Block is a set of statements defined between curly brasses '{ }'. We can write the blocks inside the class and also inside the methods. Blocks defined inside the class are called as instance blocks, blocks defined inside the methods are called as local blocks. Static keyword We can use the static keyword for variables, methods and blocks. Static variables : Memory will be allocated for static variables at class loading time. Static blocks will be executed at class loading time. Static methods will be executed when you call it. The main advantage of static method is that no object or reference variable is required to invoke the static method .with the class-name, we can invoke the static method. Local variables cannot be static and local blocks cannot be static. If we declare a variable or a block as static inside a method, compiler gives the following error." illegal start of expression".

Difference between Static variables and Instance variables


Static variables 1. Variable declared inside a class with the static keyword is called static variable. 2. Memory will be allocated for static variable when we are loading class into the memory. 3. Only one copy of static variable will be created for 'n' number of objects. 4. static variables are allowed to use inside static blocks, instance blocks, Instance variables 1. Variable declared inside a class without the static keyword is called instance variable. 2. Memory will be allocated for instance variable when we are creating a object. 3. 'n' copies of instance variables will be created for 'n' number of objects. 4. Instance variables are allowed to use inside instance blocks and instance

static method and non-static methods.

method. These are not allowed to use inside static blocks and static method.

Static methods : A method which is declared with the static keyword is called static method. A method without static keyword is called non-static method or instance method. Note : 1. Inside non-static method both static and non-static variables are allowed. 2. Inside a static method only static variables are allowed. Static Blocks : Blocks declared with static keyword called static blocks and blocks declared without static keyword is called non-static blocks. Inside the static block only static variables are allowed. Inside the non-static block both static and non-static variables are allowed. Static block will be executed when we are loading class into memory. Non-static block will be executed when we are creating object.

OOPS IN JAVA
There are following oops Concepts : Abstraction Encapsulation Inheritance Polymorphism To describe object, there are two important rules in java : Properties , also called Variables. Operations , also called Methods. Abstraction : Providing necessary operations and properties of certain object by hiding internal details is called Abstraction. Encapsulation : Placing the data and operations which are going to operate on data in a single entity is called Encapsulation. Inheritance : Creating a new class by using the functionality of existing class.This new class is called subclass or child class or derived class .The existing class is called super class or parent class or base class. Main use of interitance is reusability. Polymorphism : A process of behaving one form differently in different situation is called polymorphism.It is to create multiple definitions for operations. These are two types : 1. Compile time polymorphism : (early binding) This can be achieved with the help of method overloading. 2. Runtime polymorphism : (late binding) This can be achieved with the help of method overriding. Objects & Classs : Class is a logical entity which is a template or plan or application form for an object.Object is a physical entity which is instance of the class.
Declaring the class : syntax: class classname {

Datatype variable1,variable2,? return type method name(parameters) { ------------------------} }

Variables and methods are called as members of the class.


Ex: class Student { int sno=3; String sname="sri"; Void display() { System.out.println("Student id no is:"+sno); System.out.println("Student name is:"+sname); } } Creating object : Syntax: class-name reference variable = new class-name(); Ex: Student s= new Student(); One object will be created for Student class. In the above example 's' is the reference variable . Student () is the constructor of Student class. Calling the members of the class : Syntax: Object-name. member name Ex: s.display(); Example: class Student { int sno=3; String sname="sri"; Void display() { System.out.println("Student id no is:"+sno); System.out.println("Student name is:"+sname); } } class Demo { public static void main(String as[]) { Student s= new Student(); s.display(); } } s- is a reference variable.

OOPS IN JAVA-II
Abstract class :Example :abstract class Animal { abstract void eat(); void show() { System.out.println("This is Animal show"); } class Demo { public static void main(String as[]) { Animal a=new Animal(); //not allowed. a.show(); } }

Explanation : When you are unable to implement the method (Without body) declare the method as abstract. When you declare one (or) more methods as abstract you must declare the class also abstract. When class is abstract it can't be instantiated. In an abstract class we can have both abstract method and concrete methods. In abstract class we can have only concrete methods also. When class is abstract we should write a subclass for that (or) subclass is responsible to implement the abstract class with subclass object only. We can call the subclass methods as well as abstract class concrete methods. When you extend any abstract class we should override all the abstract methods in subclass, otherwise declare the subclass as abstract. Polymorphism : There are two types of polymorphism. 1.Compile time polymorphism (or) static polymorphism 2.Runtime polymorphism (or) Dynamic polymorphism We can achieve Compile time polymorphism with method overloading. We can achieve Runtime polymorphism using method overriding. At Compile time, compiler verifies method overloading rules and to invoke these methods it won't use object. It will use parameters of the

method. At Run time JVM decides which method it has to invoke (super class method or subclass method) based on object which you are using to call the method. Note : We can assign subclass object to super class reference variable but we can't assign super class object to subclass reference variable. When class is abstract we can't create object for that but we can declare the reference variable. If we want to achieve the Runtime polymorphism, we must declare super class as abstract. Interfaces :- Need for Interfaces :The benefits of using interfaces are much the same as the benefits of using abstract classes.Interfaces provide a means to define the protocols for a class without bothering about the implementation details.This seemingly simple benefit can make large projects much easier to manage.once interfaces have been designed, the class development can take place without bothering about communication among classes. Another important use of interfaces is the capacity for a class to implement multiple interfaces.The major difference between inheriting multipleinterfaces and true multiple inheritance is that the interface approach enables you to inherit only method descriptions,implementations.If a classimplements multiple interfaces, that class must provide all the functionality for the methods defined in the interfaces. Interface is a fully abstracted class. Interface can have only final static variables and public abstract methods. Syntax :interface interface-name { datatype variable1, variable2? ------------------------------------------------------------return type method name (argument1,argument2,..); ---------------------------------}

Difference between abstract class and interface :Abstract class 1.Abstract class contains constants, variables, constructors,concrete methods and abstract methods. 2.Use extends keyword to extend the abstract class. 3.Abstract class doesn't support multiple inheritance i.e. after extends keyword more than one class name is not allowed. 4.When you are writing abstract methods in abstract class we should write abstract keyword. 5.If you want to declare final static variable and public abstract methods in abstract class, we should declare them explicitly. interface 1.Interface contains constants and public abstract methods. 2.Use 'implements' keyword to implement the interface. 3.Interface support multiple inheritance i.e. after implements keyword more than one class name is allowed. 4.When you are writing abstract methods in interface, no need to write abstract keyword.

Using super Keyword

The base class constructor can be called in a derived class or subclass using super() in the constructor. Example :
class A { int a; A() { System.out.println ("This is A default constructor"); } A (int a) { this. a=a; System.out.println ("This is A one arg constructor"+a); } } class B { B() { super(); System.out.println ("This is B default constructor"); } B (int a,int b) { super (a); this.b=a; System.out.println ("This is B one arg constructor"+b); } } class ConstructorOverloading { public static void main (String as[]) { B b1= new B (); B b2= new B(99,88); } } Output: This is A default constructor.

This is A one arg constructor 99 This is B default constructor This is B one arg constructor 88.

When you have super class and subclass, with subclass object we can call both subclass members and super class members. Super class object is not required, but when you create super class object then only superclass constructor will be invoke. Using super keyword ,we can invoke the super class constructor without creating superclass object. We can write super with different signatures like : super(a); super(a,b); super(a,b,c..); When you are not writing any super() JVM insert default super(). When you are writing super(), JVM won't insert default super(). Super() must be the first line in the constructor. More than one super() is not allowed inside a constructor. Both this() and super() are not allowed inside a constructor at a time. Constructor invoking order is from bottom to top (subclass to super class). Constructor execution order is from top to bottom (super class to subclass).

Inheritance : Deriving a new class from existing class is class Inheritance. The main use of Inheritance is reusability. Syntax:
Class newclass-name extends existing class { Datatype variable1,variable2,?? returntype method() { ------------------} }

Inheritance
Example :
class CD { String title="inheritance"; String author="javasree"; void display() { System.out.println ("title is:"+ title); System.out.println ("author is:"+author); } } class VCD extends CD { String newfeature="SD SOFT"; void show() { System.out.println ("new feature is: "+newfeature); } } class Demo { public static void main(String as[]) { VCD c = new VCD (); c.show (); c.display (); } }

Output :

new feature is: SD SOFT title is: inheritance author is: javasree

Explanation : When you extend any class all the superclass members becomes members of subclass. With subclass object we can call subclass members as well as superclass members also. With superclass object we can call only superclass members. We can't call subclass members. Types of Inheritance : 1. Simple Inheritance 2. Multilevel Inheritance

3. Hierarchal Inheritance 4. Multiple Inheritance 5. Hybrid Inheritance 1.Simple Inheritance : In this process we can have only one super class and one subclass.

2.Multilevel Inheritance : The process of deriving of new class from already derived class is called multilevel inheritance.In this ,A is a superclass and two subclasses B,C. C is a subclass and has superclass called A and B.

3. Hierarchal Inheritance : In this process we have onesuperclass and many subclasses. In this one superclass and many subclasses. In the following diagram, A is superclass and B, C are subclasses.

4.Multiple Inheritance : (not allowed in java) In this process we have one subclass and many super classes.

Note: Java doesn't support multiple Inheritance using classes. In this one subclass can have many direct super classes. 5.Hybrid Inheritance :(not allowed in java) It is combination of multilevel and multiple and herarical inheritance.

Note: Java doesn't support hybrid Inheritance using classes.

MULTITHREADING
Introduction to Threads :A thread is a single independent path of execution with a program. When a program runs, it starts executing the initial code and the subsequent methods and then continues the processing until the program is exited. This program uses a single thread where the thread is a single locus of control for the program.

Definition of a Thread :"Thread is a part of a program which has separate part of execution."

Difference between Process Based Multitasking And Thread Based Multitasking :Process Based Multitasking 1.Different Memory spaces will be allocated for different process. 2.Context-switching between processes is very expensive. Thread Based Multitasking 1.Only one Memory space will be allocated for different threads. 2.Context-switching is very easy because some life-cycles methods provided for this

3.Communication between processes 3.Communication between threads is very expensive. is very easy. 4.Executing more than one process (or) program concurrently is called process based multitasking. 4.Executing more than one thread concurrently is called thread based multitasking.

Creating Threads in Java : We can create the thread in java in two ways. 1.By implementing a Runnable interface. 2.By Extending the Thread class. Threads what you have creating using these two ways are called as child threads. Child threads must be started from main thread. Main thread is a thread which created and started by JVM when you are running the java program with main method.

Example for Thread :class Thread { public static void main(String as[]) { Thread t=Thread.currentThread(); System.out.println(t); System.out.println(t.getName()); System.out.println(t.getPriority()); for(int i=0;i<5;i++) { System.out.println("Thread"); } try { t.sleep(500); } catch(Exception e) {}

} }

Creating a thread By using Implementing Runnable Interface :Any class whose instances are intended to be executed by a thread should implement the Runnable interface. The class implementing the Runnable interface must define run() method. The only method in Runnable interface is public void run(), which need to be overridden. All the tasks that the thread is supposed to execute is defined inside the run() method. For example :class MyThreadClass implements Runnable { int x; String name; Public MyThreadClass(String n) { name=n; } public void run() { for(x=0;x<10;x++) { System.out.println(name); } }

} public class MainThreadClass { public void main(String args[]) { MyThreadClass tc1=new MyThreadClass("Hai?"); MyThreadClass tc2=new MyThreadClass("Hello?"); Thread t1=new Thread(tc1); Thread t2=new Thread(tc2); t1.start(); t2.start(); } }

Creating a thread by using Extending Thread Class :The second way of creating threads is by extending the Thread class. The following program extends the Thread class to create thread.
public class MyThread extends Thread { public void run() { System.out.println("Thread is running now??."); } public void start() { run(); } public static void main(String args[]) { MyThread t=new MyThread(); t.start(); } }

Thread Priorities :Priority of a thread is an integer number, ranging from 1 to 10 .Where '1' is lowest and 10 is highest. Sun has given three constant related to these thread class.
1.MIN_PRIORITY 2.NORM_PRIORITY 3.MAX_PRIORITY Minimum priority of thread is '1'. Normal priority of thread is '5'. Maximum priority of thread is '10'.

We can modify the priority of thread and we can get available priority of thread using the following methods.
void setPriority(int x) int getPriority()

THREAD LIFE-CYCLE :-

Thread life-cycle :As a programmer you have to create a thread and start.The thread will be in "readytorun" state. JVM call run method on thread by using scheduling algorithms which means that when CPU time is allocated for the thread JVM calls the run() method on that thread. After calling the run() thread will be in running state. When we call sleep on running thread by specifying some amount of time thread will be entered into sleeping state. After the elapsed time is over thread will be moved from sleeping state to readytorun state. When we call wait() on running thread, thread will be entered into wait state,to send the waiting thread to readytorun state we have to call notify() or notifyAll().System uses LRE(Least Recently Used) algorithm to move the thread from waiting state to readytorun state. When the thread is waiting for a resource which is not available. The thread will be moved to blocked state, when that resource is available latter the thread will be entered into readytorun state.

When we call stop() or destroy() on thread, it will enter into dead state.

Deadlock : Consider two threads A and B. A is holding resource R1 and waiting for resource R2.B is holding resource R2 and is waiting for resource R1. A will release R1 After getting R2 and B will release R2 after getting R1 only. A and B waiting for R1and R2 mutually. This situation is called deadlock.

Daemon Threads : Daemon threads are service threads, these threads depends on child threads and provide the service to child threads as long as child threads are running, daemon threads will run and will provides service. We can check whether the thread is daemon thread or not by using the following method. boolean isDaemon(); We can set as Daemon thread with the following method. void setDaemon();

SYNCHRONIZATION :In multi-threaded environment, you want to allow only one thread to access the give object i.e. you don't want to allow to accept the given object concurrently to achieve this we need to apply synchronization. We have two ways to apply the Synchronization. 1.Method level Synchronization. 2.Block level Synchronization. Example :- For Method level
public synchronized void getData() { x++; }

Example :-For Block level


public void getData()

synchronized(this) { x++; }

IOSTREAMS
Overview of java.io's Input and Output Streams : The java.io package contains two classes, InputStream and OutputStream, from which most of the other classes in the package are derived. The InputStream class is an abstract base class that provides a minimal programming interface and a partial implementation of input streams in Java.The InputStream class defines a methods for reading bytes or arrays of bytes, marking locations in the stream, skipping bytes of input, finding out the number of bytes that are available for reading, and resetting the current position within the stream. An input stream is automatically opened when you create it. You can explicitly close a stream with the close() method, or let it be closed implicitly when the object is garbage collected. The OutputStream class is an abstract base class that provides a minimal programming interface and a partial implementation of output streams in Java. OutputStream defines methods for writing bytes or arrays of bytes to the stream and flushing the stream. An output stream is automatically opened when you create it. You can explicitly close an output stream with the close() method, or let it be closed implicitly when the object is garbage collected. The java.io package contains several subclasses of InputStream and OutputStream that implement a specific input or output function. For example, FileInputStream and FileOutputStream are input and output streams that operate on a file on the native file system. The first of the following two diagrams shows the class hierarchy for the input stream classes comprising the java.io package. InputStream inherits from the Object class; six classes inherit directly from InputStream. One of OutputStream's descendents, FilterInputStream, is itself an abstract class with four children. The second of the diagram shows the class hierarchy for the output stream classes contained in the java.io package. OutputStream inherits from the Object class; four classes inherit directly from OutputStream. One of OutputStream's descendents, FilterOutputStream, is itself an abstract class with three descendents.

I/O Streams Hierarchy Chart : The following is an overview of the input and output stream classes that inherit directly from InputStream and OutputStream that are not themselves abstract classes. FileInputStream and FileOutputStream : Used to read data from or write data to a file on the native file system. PipedInputStream and PipedOutputStream : Implements the input and output components of a pipe. Pipes are used to channel the output from one program (or thread or code block) into the input of another. A PipedInputStream must be connected to a PipedOutputStream and vice versa.

ByteArrayInputStream and ByteArrayOutputStream : Reads data from or writes data to a byte array in memory. SequenceInputStream : Concatenates multiple input streams into one input stream. StringBufferInputStream : Allows programs to read from a StringBuffer as if it were an input stream. We have two types of streams based on the type of data it transfers : 1)byte streams : All the byte streams are subclasses of inputstream and outputstream abstract classes. Byte Streams are used to read or write binary data. 2)character streams : All the character streams are subclasses of Reader and Writer abstract classes. Character Streams are used to read characters which are represented by Unicode character set. We can achieve internationalization (i18n) through character streams.

Byte Streams
InputStream FileInputStream BufferedInputStream ObjectInputStream FilteredInputStream DataInputStream PipedInputStream OutputStream FileOutputStream BufferedOutputStream ObjectOutputStream FilteredOutputStream DataOutputStream PipedOutputStream

Character Streams
Reader FileReader BufferedReader ObjectReader FilteredReader DataReader PipedReader FileWriter BufferedWriter ObjectWriter FilteredWriter DataWriter PipedWriter Writer

Serialization

Java serialization is a simple but powerful feature of the java language. Java uses call by value for the primitives and callbyreference for objects. These two concepts are good enough in a single machine. When we are working with distributed environments like RMI, EJB, CORBA, etc. you will get a chance to pass data from one machine to another machine. The data may be primitive data or objects. Primitive values will be moved from one machine to another remote machine easily, no issues in this mechanism. If the data is in the form of object, java uses call by reference. i.e, address of that object will be passed to remote machine which is meaningless.Here is the problem. To solve this problem we need to use serialization. How to Make a Class Serializable : To make a class serializable, just declare that this class implements the interface Serializable.Serializable is a marker interface.
class Student implements java.io.Serializable { String lName; String fName; double fee;

String address; }

The best thing is that Serializable interface does not force you to implement any methods, that's why modification of the class Student was minimal. All attributes of the class Student must have either primitive data types, or represent objects that are also serializable. How to Serialize an Object : To serialize an object into a stream perform the following actions : Open one of the output streams, for example FileOutputStream Chain it with the ObjectOutputStream Call the method writeObject() providing the instance of a Serializable object as an argument. Close the streams The following example performs all these steps and creates a snapshot of the object Student in the file called NewStudent.ser
import java.io.*; import java.util.Date; public class StudentRecords{ public static void main(String[] args) { Student stu = new Student(); stu.lName = "John"; stu.fName = "Smith"; stu.fee = 10000; stu.address = "12 main street"; FileOutputStream fOut=null; ObjectOutputStream oOut=null; try{ fOut= new FileOutputStream("c:\\NewStudent.ser"); oOut = new ObjectOutputStream(fOut); oOut.writeObject(stu); //serializing employee System.out.println( "A student is serialized into c:\\NewStudent.ser"); }catch(IOException e){ e.printStackTrace(); }finally{ try { oOut.flush(); oOut.close(); fOut.close(); } catch (IOException e1) { e1.printStackTrace(); } } } }

If you do not want to serialize sensitive information such as fee, declare this variable using the keyword transient : Syntax : transient double fee;

Note : The values transient member variables are not serialized. How to Deserialize an Object To deserialize an object perform the following steps: Open an input stream Chain it with the ObjectInputStream Call the method readObject() and cast the returned object to the class that is being deserialized. Close the streams The next example reads our file NewStudent.ser and recreates the instance of the object Student :
import java.io.*; public class StudentRecords { public static void main(String[] args) { FileInputStream fIn=null; ObjectInputStream oIn=null; try{ fIn= new FileInputStream("c:\\NewStudent.ser"); oIn = new ObjectInputStream(fIn); //de-serializing Student Student stu = (Student) oIn.readObject(); System.out.println("Deserialized " + stu.fName + " " + stu.lName + " from NewStudent.ser "); }catch(IOException e){ e.printStackTrace(); }catch(ClassNotFoundException e){ e.printStackTrace(); }finally{ try { oIn.close(); fIn.close(); } catch (IOException e1) { e1.printStackTrace(); } } } } The class StudentRecords will produce the following output : Deserialized Smith John from NewStudent.ser Note : We did not explicitly created an instance of the object Student- JVM did it for us. Make sure that definition of the class Student is available to JVM that reads the

stream. In distributed applications it usually runs on a remote machine. During the process of deserialization all transient variables will be initialized with default values according to their type, for example integer variables will have the value of zero. Serialization in the Real World In some types of applications you have to write the code to serialize objects, but in many cases serialization is performed behind the scenes by various server-side containers. These are some of the typical uses of serialization : To persist data for future use. To send data to a remote computer using such client/server Java technologies as RMI or socket programming. To "flatten" an object into array of bytes in memory. To exchange data between applets and servlets. To store user session in Web applications. To activate/passivate enterprise java beans. To send objects between the servers in a cluster.

If performance is your primary goal, use Externalizable interface instead of Serializable. Yes, you'll have to write code to serialize each attribute, but this may speed up serialization process substantially.

Marshalling and unmarshalling : It's not too difficult for JVM to convert a primitive integer variable into four bytes for serialization, but it's not as simple in case of classes containing variables with references to other objects. The process of converting such complex object into a sequence of bytes is called marshalling and the process of reconstructing of the objects from these bytes is called unmarshalling and Java does this job for you.

CORE API
ArrayList API public class ArrayList implements List,RandomAccess,Cloneable,Serializable { ArrayList(); ArrayList(int); ArrayList(Collection); void trimToSize(); protected void removeRange(int,int); } Arrays API public class Arrays extends Object { void sort(XXX[]); int binarySearch(XXX[],xxx); void fill(XXX[],XXX); void sort(XXX[],int,int); void fill(XXX[],int,int,XXX); boolean equals(byte[]); void sort(Object[],int,int,Comparator); void sort(Object[],Comparator); int binarySearch(Object[],Object,Comparator); } Collection API interface Collection { int hashCode(); int size(); void clear(); boolean isEmpty(); Object[] toArray();

boolean add(Object); boolean contains(Object); boolean equals(Object); boolean remove(Object); boolean addAll(Collection); boolean containsAll(Collection); boolean removeAll(Collection); boolean retainAll(Collection); Iterator iterator(); Object[] toArray(Object[]); } Date API public class Date implements Serializable,Cloneable,Comparable { Date(); Date(int,int,int); Date(String); int getDate(); int getDay(); int getHours(); int getMinutes(); int getMonth(); int getSeconds(); int getYear(); long getTime(); } Enumeration API interface Enumeration { boolean hasMoreElements(); Object nextElement(); } HashMap API

class HashMap implements Map,Cloneable,Serializable { HashMap(); HashMap(int); HashMap(int,float); HashMap(Map); void addEntry(int,Object,Object,int); } Iterator API interface Iterator { void remove(); boolean hasNext(); Object next(); } List API interface List extends Collection { Object get(int); Object remove(int); void add(int,Object); int indexOf(Object); int lastIndexOf(Object); boolean addAll(int,Collection); List subList(int,int); ListIterator listIterator(); ListIterator listIterator(int); Object set(int,Object); } ListIterator API interface ListIterator extends Iterator

{ int nextIndex(); int previousIndex(); void remove(); boolean hasNext(); boolean hasPrevious(); Object next(); Object previous(); void add(Object); void set(Object); } Map API interface Map { int hashCode(); int size(); void clear(); boolean isEmpty(); boolean containsKey(Object); boolean containsValue(Object); boolean equals(Object); Collection values(); void putAll(Map); Set entrySet(); Set keySet(); Object get(Object); Object remove(Object); Object put(Object,Object); } Set API interface Set extends Collection { int hashCode(); int size(); void clear();

boolean isEmpty(); Object[] toArray(); boolean add(Object); boolean contains(Object); boolean equals(Object); boolean remove(Object); boolean addAll(Collection); boolean containsAll(Collection); boolean removeAll(Collection); boolean retainAll(Collection); Iterator iterator(); Object[] toArray(Object[]); } Vector API class Vector implements List,RandomAccess,Cloneable,Serializable { protected int elementCount; Vector(); Vector(int); Vector(Collection); synchronized int size(); synchronized void removeAllElements(); synchronized boolean isEmpty(); synchronized void removeElementAt(int); Vector(int,int); protected void removeRange(int,int); synchronized Object clone(); synchronized Object firstElement(); synchronized Object lastElement(); synchronized Object elementAt(int); synchronized int lastIndexOf(Object); synchronized void addElement(Object); synchronized boolean removeElement(Object); synchronized int indexOf(Object,int); synchronized int lastIndexOf(Object,int); synchronized void insertElementAt(Object,int);

Enumeration elements(); } Collections API public class Collections { Comparator reverseOrder(); void reverse(List); void sort(List); void swap(List,int,int); Object max(Collection); Object min(Collection); int binarySearch(List,Object); void fill(List,Object); ArrayList list(Enumeration); Collection synchronizedCollection(Collection); Collection unmodifiableCollection(Collection); void sort(List,Comparator); Enumeration enumeration(Collection); List singletonList(Object); List synchronizedList(List); List unmodifiableList(List); void copy(List,List); Map synchronizedMap(Map); Map unmodifiableMap(Map); Set singleton(Object); Set synchronizedSet(Set); Set unmodifiableSet(Set); SortedMap synchronizedSortedMap(SortedMap); SortedMap unmodifiableSortedMap(SortedMap); SortedSet synchronizedSortedSet(SortedSet); SortedSet unmodifiableSortedSet(SortedSet); boolean replaceAll(List,Object,Object); Object max(Collection,Comparator); Object min(Collection,Comparator); static Collection synchronizedCollection(Collection,Object); int binarySearch(List,Object,Comparator); List synchronizedList(List,Object); Map singletonMap(Object,Object);

static Set synchronizedSet(Set,Object); } Math API public final class java.lang.Math extends java.lang.Object { public static final double E; public static final double PI; public static strictfp double random(); static {}; public static strictfp double abs(double); public static strictfp double acos(double); public static strictfp double asin(double); public static strictfp double atan(double); public static strictfp double ceil(double); public static strictfp double cos(double); public static strictfp double exp(double); public static strictfp double floor(double); public static strictfp double log(double); public static strictfp double rint(double); public static strictfp double sin(double); public static strictfp double sqrt(double); public static strictfp double tan(double); public static strictfp double toDegrees(double); public static strictfp double toRadians(double); public static strictfp long round(double); public static strictfp double IEEEremainder(double,double); public static strictfp double atan2(double,double); public static strictfp double max(double,double); public static strictfp double min(double,double); public static strictfp double pow(double,double); public static strictfp float abs(float); public static strictfp int round(float); public static strictfp float max(float,float); public static strictfp float min(float,float); public static strictfp int abs(int); public static strictfp int max(int,int); public static strictfp int min(int,int); public static strictfp long abs(long);

public static strictfp long max(long,long); public static strictfp long min(long,long); } Runtime API public class Runtime extends Object { native int availableProcessors(); native long freeMemory(); native long maxMemory(); native long totalMemory(); native void gc(); void runFinalization(); void exit(int); void halt(int); static Runtime getRuntime(); void load(String); void loadLibrary(String); Process exec(String) throws IOException; } System API final class System extends Object { static final InputStream in; static final PrintStream out; static final PrintStream err; static void gc(); static void runFinalization(); static void exit(int); static void setIn(InputStream); static void setErr(PrintStream); static void setOut(PrintStream); static SecurityManager getSecurityManager(); static void setSecurityManager(SecurityManager); static void load(String); static void loadLibrary(String); static Properties getProperties();

static void setProperties(Properties); static String getProperty(String); } Class API final class Class extends Object implements Serializable { native int getModifiers(); native boolean isArray(); native boolean isInterface(); native boolean isPrimitive(); native Class getSuperclass(); Class[] getClasses(); native Class[] getInterfaces(); ClassLoader getClassLoader(); Object newInstance() throws java.lang.InstantiationException native Object[] getSigners(); native boolean isInstance(Object); native void setSigners(Object[]); Package getPackage(); native String getName(); String toString(); reflect.Constructor[] getConstructors(); reflect.Field[] getFields(); reflect.Method[] getMethods(); static Class forName(String); throws java/lang/ClassNotFoundException }

COLLECTION FRAMEWORK
Introduction :The java collection framework standardizes the way in which groups of objects are handled your programs. Before to java2 we had five legacy classes. They are 1.Dictionary 2.Vector 3.Stack 4.Hash Table 5.Properties Among these, Vector and Stack are used to store set of objects. Dictionary, Hashtable and Property classes are used to store Key-value pairs. And we had one legacy interface called Enumeration which is used to visit the elements of legacy class.All the legacy classes are synchronized bydefault.When object is synchronized only one thread is allowed to access that object at a time which results "system will slow and it will take moreime".To avoid this problems Sun has introduced Collection Framework from java2.

Hierarchy Structure of Collection Framework :-

Collection Framework has three categories. 1.List 2.Set 3.Map List is used to store collection of objects. List allows duplicates. Set also used to store collection of objects. Set does not allow duplicates. Map is used to store key-value pairs.

ArrayList : ArrayList class is sub class of list which is implementing marker interfaces called random access clonable and serializable. ArrayList is used to store group of objects similar or dissimilar objects. ArrayList allows duplicates. Objects in the array list will be store internally using index notation. ArrayList is not synchronized by default because it is a collection class.

Vector : Vector is a sub class of list whose functionality is very similar to array list. Sun has reengineered vector has a sub class of list to make use of functionality of list and collection interfaces. The main difference between vector and array list is "vector is synchronized by default where as array list is not synchronized by default".

Difference between ArrayList and Vector List :ArrayList Vector List 2.Vector list can use Iterator and Enumeration Interface to access the elements.

1.ArrayList is not synchronized by default. 1.Vector List is synchronized by default. 2.ArrayList can use only Iterator to access the elements.

3.ArrayList is implementing Random 3.Vector list is implements random access Access marker interface. Because of this we can marker interface because of this we can pick pickup the elements randomly from vector the elements 4.JVM using Index notation to store the array list internally. 4.JVM will use Index notation to store the vector list internally.

Vector : Set is a collection of interface which does not allow duplicates. This interface has three sub classes. 1.Hash Set 2.Tree Set 3.Linked Hash Set

Difference between Hash set and Tree Set :HashSet TreeSet

1.HashSet is under set interface i.e. it 1.TreeSet is under set i.e. it does not guarantee for either sorted provides elements in a sorted order or sequence order. order (acceding order). 2.We can add any type of elements to hash set. 2.We can add only similar types of elements to tree set.

Map Interface : Map interface is used to store key-value pairs. Map is a part of collection framework but it not under collection interface.

Sub-class of Map :1.Hash Map 2.Hashtable 3.TreeMap 4.LinkedHashMap

HashMap : HashMap is an unordered set. HashMap does not allow duplicate keys and is allow duplicate values. HashMap will allow null keys and null values.

Hash Table : Hashtable is a legacy class which was recognized as a subclass of map interface. Hashtable does not allow null values. HashMap 2.HashMap allows null keys. 3.HashMap allows null values HashTable 2.Hashtable does not allow null keys. 3.Hashtable does not allow null values.

1.HashMap is not synchronized by default. 1.Hashtable is synchronized by default.

Similarities of Hash map and hash table : Both HashMap and Hashtable does not allows duplicate keys but both allow duplicate values. Both HashMap and Hashtable are unordered maps.

TreeMap : TreeMap is a sorted map i.e. which gives the entries in sorted order using keys. Null keys are not allowed. Duplicate keys are not allowed. Null values are allowed. Duplicate values are allowed.

JNDI Tutorial
Introduction:
DataSource JNDI name is nothing but a name that is used to bind the datasource object in the JNDI registry. We are going to use JNDI naming service to bind and lookup the datasourse objects. Sun has provided JNDI API for the developers to access JNDI registry.The package provided is javax.naming. Datasource object will be binded in the JNDI registry by the container automatically. As a developer you have to use lookup methods to get connection from DataSource object. The JNDI architecture consists of an API (Application Programming Interface) and an SPI (Service Provider Interface). Java applications use this API to access a variety of naming and directory services. The SPI enables a variety of naming and directory services to be plugged in transparently, allowing the Java application using the API of the JNDI technology to access their services.

Features:
The J2EE Engine Naming System is a connected set of contexts of the same type that perform naming-related operations. Use the JNDI Registry Service to look up an object from the naming system by supplying it the name of the object (as a String or Name). The service associates names with objects and also enables these objects to have attributes. As a result, you can look up an object not only by its name, you can also get the object's attributes or search for the object based on its attributes. When you search, you can enter not a name but a query, consisting of a logical expression, in which you specify the attributes that the object or objects must have. The service returns the objects that satisfy the search filter.

The JNDI Registry Service basic concepts are:


Naming concepts - if you want to associate an object with a particular name, you have to bind it in the J2EE Engine naming system. Once the object is bound, it can be accessed through the lookup operations and through the operations for working with names (rename, rebind, unbind). Directory concepts - the DirContext that inherits Context provides operations through which you can associate not only an object with a specified name, but also with specified attributes. If you have, for example, an object named car you can associate it except with

its name or with particular attributes, such as brand name, color, number of doors, number of seats, and so on.

JNDI Packages:
The JNDI consists of five packages: javax.naming :This package contains classes and interfaces for accessing naming services. javax.naming.directory :This package extends the core javax.naming package to provide functionality for accessing directories in addition to naming services. javax.naming.event :This package contains classes and interfaces for supporting event notification in naming and directory services. javax.naming.ldap :This package contains classes and interfaces for supporting LDAPv3 extended operations and controls. javax.naming.spi:This package contains the classes and interfaces that allow various naming and directory service providers to be dynamically plugged in beneath the JNDI.

javax.naming package Description


Provides the classes and interfaces for accessing naming services. This package defines the naming operations of the Java Naming and Directory Interface (JNDI). JNDI provides naming and directory functionality to applications written in the Java programming language. It is designed to be independent of any specific naming or directory service implementation. Thus a variety of services--new, emerging, and already deployed once--can be accessed in a common way. Example:
import import import import java.util.*; java.sql.*; javax.sql.*; javax.naming.*;

class JndiDemo { public static void main(String as[]) { int sid=0; String sname=null; try{ Properties p=new Properties(); p.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFa ctory"); p.put(Context.PROVIDER_URL,"t3://localhost:7001");

Context ctx=new InitialContext(p); Object o=ctx.lookup("jdbc/MySqlPool"); DataSource ds=(DataSource)o; Connection con=ds.getConnection(); Statement st=con.createStatement(); ResultSet rs=st.executeQuery("select * from student"); while(rs.next()) { sid=rs.getInt(1); sname=rs.getString(2); System.out.println(""+sid+"..."+sname); } rs.close(); st.close(); con.close(); }catch(Exception e) { System.out.println(e); } } } /* 1)compile: javac JndiDemo.java 2)run setEnv --------------e:\bea\user_projects\domains\javasree\setEnv.cmd 3)set classpath=%classpath%;.; 4)run: java JndiDemo */

Service Providers:
To use JNDI with a particular naming or directory service, you need a JNDI service provider, which is a module that plugs in beneath the JNDI API to access the naming or directory service. Some of the Service Providers : LDAP Service Provider: The Lightweight Directory Access Protocol (LDAP) is an Internet standard for accessing directory services. The JNDI/LDAP service provider provides access to servers implementing the LDAP protocols. The COS Naming Service Provider:The Common Object Services (COS) Name Server is the name server for storing Common Object Request Broker Architecture (CORBA) object references. It can be accessed from CORBA applications by using the COS Naming package (org.omg.CORBA.CosNaming). The JNDI/COS naming service provider implements the javax.naming.Context interface on top of the COS Naming package in order to allow applications to use JNDI to access the COS Name Server. JNDI can also be used to access other naming and directory services, in addition to the COS Name Server, thereby offering the CORBA application one interface for accessing different naming and directory services.

This document describes the features of the COS naming service provider and contains details of how JNDI is mapped to the COS naming package The RMI Registry Service Provider: The RMI registry service provider allows JNDI applications to access remote objects registered with the RMI registry. Given the location of a registry, the provider will create a naming context with bindings for the objects registered there. Such a context may be bound into another JNDI-accessible namespace (such as LDAP, for example). References to individual remote objects may likewise be bound into another namespace. A key benefit of binding registry contexts into other namespaces is location-independent access to remote objects: the RMI clients do not need to know the registry's host name or port number. RMI servers can take advantage of this to advertise their services to potential clients. In addition, remote objects can be linked into the same enterprise directory that is used to access information about people, organizations, and network resources. With this service provider installed, JNDI subsumes the functionality of the java.rmi.Naming class. This document describes the features of the RMI registry service provider.

JNDI Context:
A naming service associates names with objects. Such an association is called a binding. A set of such bindings is called a context, which provides a resolution or lookup operation that returns the object. Other operations may include binding and unbinding names, and listing bound names. Note that a name in one context object can be bound to another context object that has the same naming convention. This is called a subcontext. In JNDI, a context is represented using the javax.naming.Context interface, which is the key interface for interacting with a naming service. Each naming method in the Context interfaces has two overloaded forms: lookup(String name): accepts a string name lookup(javax.naming.Name): accepts a structured name such as CompositeName (a name that spans multiple naming systems) or CompoundName (a name in a single naming system); both implement the Name interface. The javax.naming.InitialContext is a class that implements the Context interface. Use this class to serve as your entry point to the naming service. To create an InitialContext object, the constructor takes a set of properties in the form of java.util.Hashtable or one of its subclasses, such as Properties.

Here is an example:
Properties p=new properties(); // select a service provider factory hs.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); // create the initial context Context ctx = new InitialContext(p);

The INITIAL_CONTEXT_FACTORY specifies the name of a factory class in a JNDI service provider. The factory is responsible for creating a suitable InitialContext object for its service. In the above snippet of code, a factory class for the file system service provider is specified.

Conclusion:
The JNDI is a set of APIs that can enhance your network applications with naming/directory services.

RMI Tutorial
RMI:

The Java Remote Method Invocation (RMI) system allows an object running in one Java virtual machine to invoke methods on an object running in another Java virtual machine. RMI provides for remote communication between programs written in the Java programming language.

An Overview of RMI Applications

RMI applications often comprise two separate programs, a server and a client. A typical server program creates some remote objects,makes references to these objects accessible, and waits for clients to invoke methods on these objects. A typical client program obtains a remote reference to one or more remote objects on a server and then invokes methods on them. RMI provides the mechanism by which the server and the client communicate and pass information back and forth.Such an application is sometimes referred to as a distributed object application. Distributed object applications need to do the following: Locate remote objects: . Applications can use various mechanisms to obtain references to remote objects. For example, an application can register its remote . objects with RMI's simple naming facility, the RMI registry. Alternatively, an application can pass and return remote object references as part of other remote invocations. Communicate with remote objects: . Details of communication between remote objects are handled by RMI. To the programmer, remote communication looks similar to regular Java method invocations. Load class definitions for objects that are passed around: . Because RMI enables objects to be passed back and forth, it provides mechanisms

for

for loading an object's class definitions as well as

transmitting an object's data. The following illustration depicts an RMI distributed application that uses the RMI registry to obtain a reference to a remote object.The server calls the registry to associate (or bind) a name with a remote object. The client looks up the remote object by its name in the server's registry and then invokes a method on it. The illustration also shows that the RMI system uses an existing web server to load class definitions,from server to client and from client to server,for objects when needed.

Remote Interfaces, Objects, and Methods

Like any other Java application, a distributed application built by using Java RMI is made up of interfaces and classes. The interfaces declare methods. The classes implement the methods declared in the interfaces and, perhaps, declare additional methods as well. In a distributed application, some implementations might reside in some Java virtual machines but not others.Objects with methods that can be invoked across Java virtual machines are called remote objects. An object becomes remote by implementing a remote interface, which has the following characteristics: . A remote interface extends the interface java.rmi.Remote. . Each method of the interface declares java.rmi.RemoteException in its throws clause, in addition to any application-specific exceptions. RMI treats a remote object differently from a non-remote object when the object is passed from one Java virtual machine to another Java virtual machine.Rather than making a copy of the implementation object in the receiving Java virtual machine, RMI

passes a remote stub for a remote object. The stub acts as the local representative, or proxy, for the remote object and basically is, to the client,the remote reference. The client invokes a method on the local stub, which is responsible for carrying out the method invocation on the remote object.

Creating Distributed Applications by Using RMI


Developing a distributed application Using RMI involves these general steps: 1.Designing and implementing the components of your distributed application. 2.Compiling sources. 3.Making classes network accessible. 4.Starting the application.

Designing and Implementing the Application Components


First, determine your application architecture, including which components are local objects and which components are remotely accessible. This step includes: Defining the remote interfaces. . A remote interface specifies the methods that can be invoked remotely by a client.Clients program to remote interfaces, . not to the implementation classes of those interfaces. The design of such interfaces includes the determination of the types . of objects that will be used as the parameters and return values for these methods.If any of these interfaces or classes do not yet exist, you need to define them as well. Implementing the remote objects. . Remote objects must implement one or more remote interfaces. The remote object class may include implementations of other interfaces and methods that are available only locally.If any local classes are to be used for parameters or return values of any of these methods,they must be implemented as well. Implementing the clients.

any time after remote objects

. Clients that use remote objects can be implemented at the remote interfaces are defined,including after the have been deployed.

Designing a Remote Interface


At the core of the compute engine is a protocol that enables tasks to be submitted to the compute engine,the compute engine to run those tasks, and the results of those tasks to be returned to the client. This protocol is expressed in the interfaces that are supported by the compute engine. The remote communication for this protocol is illustrated in the following figure.

Each interface contains a single method. The compute engine's remote interface, Compute, enables tasks to be submitted to the engine. The client interface, Task, defines how the compute engine executes a submitted task. The javasree.Compute interface defines the remotely accessible part, the compute engine itself. Here is the source code for the Compute interface:

package javasree; import java.rmi.Remote; import java.rmi.RemoteException; public interface Compute extends Remote { <T> T executeTask(Task<T> t) throws RemoteException; }
By extending the interface java.rmi.Remote, the Compute interface identifies itself as an interface whose methods can be invoked from another Java virtual machine. Any object that implements this interface can be a remote object. As a member of a remote interface, the executeTask method is a remote method. Therefore, this method must be defined as being capable of throwing a

java.rmi.RemoteException. This exception is thrown by the RMI system from a remote method invocation to indicate that either a communication failure or a protocol error has occurred.A RemoteException is a checked exception, so any code invoking a remote method needs to handle this exception by either catching it or declaring it in its throws clause. The second interface needed for the compute engine is the Task interface, which is the type of the parameter to the executeTask method in the Compute interface. The compute.Task interface defines the interface between the compute engine and the work that it needs to do, providing the way to start the work. Here is the source code for the Task interface:

package javasree; public interface Task<T> { T execute(); }


The Task interface defines a single method, execute, which has no parameters and throws no exceptions. Because the interface does not extend Remote, the method in this interface doesn't need to list java.rmi.RemoteException in its throws clause. The Task interface has a type parameter, T, which represents the result type of the task's computation. This interface's execute method returns the result of the computation and thus its return type is T. The Compute interface's executeTask method, in turn, returns the result of the execution of the Task instance passed to it. Thus,the executeTask method has its own type parameter, T, that associates its own return type with the result type of the passed Task instance. RMI uses the Java object serialization mechanism to transport objects by value between Java virtual machines. For an object to be considered serializable, its class must implement the java.io.Serializable marker interface.Therefore, classes that implement the Task interface must also implement Serializable, as must the classes of objects used for task results. Different kinds of tasks can be run by a Hello object as long as they are implementations of the Task type.The classes that implement this interface can contain any data needed for the

computation of the task and any other methods needed for the computation. Here is how RMI makes this simple compute engine possible. Because RMI can assume that the Task objects are written in the Java programming language, implementations of the Task object that were previously unknown to the compute engine are downloaded by RMI into the compute engine's Java virtual machine as needed. This capability enables clients of the compute engine to define new kinds of tasks to be run on the server machine without needing the codeto be explicitly installed on that machine. The compute engine, implemented by the ComputeEngine class, implements the Compute interface, enabling different tasks to be submitted to it by calls to its executeTask method. These tasks are run using the task's implementation of the execute method and the results, are returned to the remote client.

Implementing a Remote Interface


This section discusses the task of implementing a class for the compute engine. In general, a class that implements a remote interface should at least do the following: . Declare the remote interfaces being implemented . Define the constructor for each remote object . Provide an implementation for each remote method in the remote interfaces An RMI server program needs to create the initial remote objects and export them to the RMI runtime, which makes them available to receive incoming remote invocations. This setup procedure can be either encapsulated in a method of the remote object implementation class itself or included in another class entirely. The setup procedure should do the following: . Create and install a security manager . Create and export one or more remote objects . Register at least one remote object with the RMI registry (or with another naming service, such as a service accessible through the Java Naming and Directory Interface) for bootstrapping purposes The complete implementation of the compute engine follows. The engine.ComputeEngine class implements the remote interface Compute and also includes the main method for setting

up the compute engine. Here is the source code for the ComputeEngine class: package javasree; import import import import java.rmi.RemoteException; java.rmi.registry.LocateRegistry; java.rmi.registry.Registry; java.rmi.server.UnicastRemoteObject;

public class ComputeEngine implements Compute { public ComputeEngine() { super(); } public T executeTask(Task t) { return t.execute(); } public static void main(String[] args) { if (System.getSecurityManager() == null) { System.setSecurityManager(new SecurityManager()); } try { String name = "Compute"; Compute engine = new ComputeEngine(); Compute stub = (Compute) UnicastRemoteObject.exportObject(engine, 0); Registry registry = LocateRegistry.getRegistry(); registry.rebind(name, stub); System.out.println("ComputeEngine bound"); } catch (Exception e) { System.err.println("ComputeEngine exception:"); e.printStackTrace(); }

} }

Creating a Client Program


The compute engine is a relatively simple program: it runs tasks that are handed to it. The clients for the compute engine are more complex. A client needs to call the compute engine,but it also has to define the task to be performed by the compute engine. Two separate classes make up the client in our example. The first class, ComputePi, looks up and invokes a Compute object.The second class, Pi, implements the Task interface and defines the work to be done by the compute engine. The job of the Pi class is to compute the value of to some number of decimal places.

The non-remote Task interface is defined as follows: package javasree; public interface Task { T execute(); } The code that invokes a Compute object's methods must obtain a reference to that object, create a Task object, and then request that the task be executed. The definition of the task class Pi is shown later. A Pi object is constructed with a single argument,the desired precision of the result. The result of the task execution is a java.math.BigDecimal representing calculated to the specified precision. Here is the source code for javasree.ComputePi, the main client class: package javasree; import import import import java.rmi.registry.LocateRegistry; java.rmi.registry.Registry; java.math.BigDecimal; compute.Compute;

public class ComputePi { public static void main(String args[]) { if (System.getSecurityManager() == null) { System.setSecurityManager(new SecurityManager()); } try { String name = "Compute"; Registry registry = LocateRegistry.getRegistry(args[0]); Compute comp = (Compute) registry.lookup(name); Pi task = new Pi(Integer.parseInt(args[1])); BigDecimal pi = comp.executeTask(task); System.out.println(pi); } catch (Exception e) { System.err.println("ComputePi exception:"); e.printStackTrace(); } } }

Like the ComputeEngine server, the client begins by installing a security manager. This step is necessary because the process of receiving the server remote object's stub could require downloading class definitions from the server. For RMI to download classes,a security manager must be in force. After installing a security manager, the client constructs a name to use to look up a Compute remote object, using the same name used by ComputeEngine to bind its remote

object. Also, the client uses the LocateRegistry.getRegistry API to synthesize a remote reference to the registry on the server's host. The value of the first command-line argument, args[0], is the name of the remote host on which the Compute object runs. The client then invokes the lookup method on the registry to look up the remote object by name in the server host's registry. The particular overload of LocateRegistry.getRegistry used, which has a single String parameter, returns a reference to a registry at the named host and the default registry port, 1099. You must use an overload that has an int parameter if the registry is created on a port other than 1099. Next, the client creates a new Pi object, passing to the Pi constructor the value of the second command-line argument, args[1], parsed as an integer. This argument indicates the number of decimal places to use in the calculation. Finally, the client invokes the executeTask method of the Compute remote object. The object passed into the executeTask invocation returns an object of type BigDecimal, which the program stores in the variable result. Finally, the program prints the result. The following figure depicts the flow of messages among the ComputePi client, the rmiregistry, and the ComputeEngine.

The Pi class implements the Task interface and computes the value of to a specified number of decimal places. For this example, the actual algorithm is unimportant. What is important is that the algorithm is computationally expensive, meaning that you would want to have it executed on a capable server. Here is the source code for client.Pi, the class that implements the Task interface: package javasree; import java.io.Serializable;

import java.math.BigDecimal; Serializable { public class Pi implements Task<BigDecimal>,

private static final long serialVersionUID = 227L; /** constants used in pi computation */ private static final BigDecimal FOUR = BigDecimal.valueOf(4); /** rounding mode to use during pi computation */ private static final int roundingMode = BigDecimal.ROUND_HALF_EVEN; /** digits of precision after the decimal point */ private final int digits; /** * Construct a task to calculate pi to the specified * precision. */ public Pi(int digits) { this.digits = digits; } /** * Calculate pi. */ public BigDecimal execute() { return computePi(digits); } /** * Compute the value of pi to the specified number of * digits after the decimal point. The value is * computed using Machin's formula: * * pi/4 = 4*arctan(1/5) - arctan(1/239) * * and a power series expansion of arctan(x) to * sufficient precision. */ public static BigDecimal computePi(int digits) { int scale = digits + 5; BigDecimal arctan1_5 = arctan(5, scale); BigDecimal arctan1_239 = arctan(239, scale); BigDecimal pi = arctan1_5.multiply(FOUR).subtract( arctan1_239).multiply(FOUR); return pi.setScale(digits, BigDecimal.ROUND_HALF_UP); } /** * Compute the value, in radians, of the arctangent of * the inverse of the supplied integer to the specified * number of digits after the decimal point. The value * is computed using the power series expansion for the

* arc tangent: * * arctan(x) = x - (x^3)/3 + (x^5)/5 - (x^7)/7 + * (x^9)/9 ... */ public static BigDecimal arctan(int inverseX, int scale) { BigDecimal result, numer, term; BigDecimal invX = BigDecimal.valueOf(inverseX); BigDecimal invX2 = BigDecimal.valueOf(inverseX * inverseX); numer = BigDecimal.ONE.divide(invX, scale, roundingMode); result = numer; int i = 1; do { numer = numer.divide(invX2, scale, roundingMode); int denom = 2 * i + 1; term = numer.divide(BigDecimal.valueOf(denom), scale, roundingMode); if ((i % 2) != 0) { result = result.subtract(term); } else { result = result.add(term); } i++; } while (term.compareTo(BigDecimal.ZERO) != 0); return result;

} }

Compiling the Example Programs


In a real-world scenario in which a service such as the compute engine is deployed, a developer would likely create a Java Archive (JAR) file that contains the Compute and Task interfaces for server classes to implement and client programs to use. Next, a developer, perhaps the same developer of the interface JAR file, would write an implementation of the Compute interface and deploy that service on a machine available to clients. Developers of client programs can use the Compute and the Task interfaces, contained in the JAR file, and independently develop a task and client program that uses a Compute service.

In this section, you learn how to set up the JAR file, server classes, and client classes. You will see that the client's Pi class will be downloaded to the server at runtime. Also, the Compute and Task interfaces will be downloaded from the server to the registry at runtime. This example separates the interfaces, remote object implementation, and client : javasree ? Compute and Task interfaces javasree ? ComputeEngine implementation class javasree ? ComputePi client code and Pi task implementation First, you need to build the interface JAR file to provide to server and client developers.

Building a JAR File of Interface Classes


First, you need to compile the interface source files in the compute package and then build a JAR file that contains their class files. Assume that user javasree has written these interfaces and placed the source files in the directory c:\programs\javasree\src\compute on Windows you can use the following commands to compile the interfaces and create the JAR file: Microsoft Windows: cd c:\programs\javasree\src javac javasree\Compute.java javasree\Task.java jar cvf javasree.jar javasree\*.class The jar command displays the following output due to the -v option: added manifest adding: javasree/Compute.class(in = 307) (out= 201) (deflated 34%) (deflated 31%) Now, you can distribute the javasree.jar file to developers of server and client applications so that they can make use of the interfaces adding: javasree/Task.class(in = 217) (out= 149)

Building the Server Classes


The javasree package contains only one server-side implementation class, ComputeEngine, the implementation of the remote interface Compute.

Assume that user ann, the developer of the ComputeEngine class, has placed ComputeEngine. java in the directory c:\programs\sri\src\javasree on Windows He is deploying the class files for clients to download in a subdirectory of her public_html directory, c:\programs\sri\public_html\classes on Windows .This location is accessible through some web servers as http://host:port/~sri/classes/. The ComputeEngine class depends on the Compute and Task interfaces, which are contained in the javasree.jar JAR file. Therefore, you need the javasree.jar file in your class path when you build the server classes. Assume that the javasree.jar file is located in the directory c:\programs\sri\public_html\classes on Windows.Given these paths, you can use the following commands to build the server classes: Microsoft Windows: cd c:\programs\sri\src javac -cp c:\programs\sri\public_html\classes\javasree.jar javasree\ComputeEngine.java

Building the Client Classes


The javasree package contains two classes, ComputePi, the main client program, and Pi, the client's implementation of the Task interface. Assume that user sudhakar, the developer of the client classes, has placed ComputePi.java and Pi.java in the directory c:\program\sudhakar\src\client on Windows. He is deploying the class files for the compute engine to download in a subdirectory of his public_html directory, c:\programs\sudhakar\public_html\classes on Windows.This location is accessible through some web servers as http://host:port/~sudhakar/classes/. The client classes depend on the Compute and Task interfaces, which are contained in the javasree.jar JAR file. Therefore, you need the javasree.jar file in your class path when you build the client classes. Assume that the javasree.jar file is located in the directory c:\programs\sudhakar\public_html\classes on Windows .Given these paths, you can use the following commands to build the client classes: Microsoft Windows:

cd c:\programs\sudhakar\src javac -cp c:\programs\sudhakar\public_html\classes\javasree.jar javasree\ComputePi.java javasree\Pi.java mkdir c:\programs\sudhakar\public_html\classes\javasree cp javasree\Pi.class c:\programs\sudhakar\public_html\classes\javasree

You might also like