Tuesday, 23 June 2015

Java Wrapper Classes

1. Introduction

The primitive data types in Java are not objects as already discussed. If we want to use these data types as objects, then we will have to use wrapper classes for each of these primitive data types provided in java.lang package.

There are many built-in classes, which cannot handle primitive data types as they deal only with objects.  One such class is Vector, which is used to store a collection of objects. We cannot use

the Vector class to directly store the collection of elements of a primitive data type. But we can do so by storing the objects of wrapper classes, which correspond to the primitive data types.

Java has a wrapper class corresponding to each of the primitive data types as shown in the following table:


2. Number class

The abstract class Number defines a super-class that is implemented by the classes that wrap the numeric types byte, short, int, long, float, and double. The number class has abstract methods that return the value of the object in each of the different number formats. These methods are:


The values returned by byteValue(), shortValue(), intValue(), longValue(), floatValue() and doubleValue() methods may involve rounding or truncation.

Example: The following example demonstrates how rounding and truncation take place when invoking methods of class Number.

class Wrapper

{ public static void main(String args[])

{ Integer iObj = new Integer(257);

System.out.println(iObj.byteValue());//truncation

Long lObj = new Long(123456789123456789L);

System.out.println(lObj);

System.out.println(lObj.doubleValue());

Float fObj=new Float(3.99f);

System.out.println(fObj.intValue());//truncation

}

}

Output:

1

123456789123456789

1.23456789123456784E17

3

3. Converting Primitive Numbers to Objects using Constructors of Wrapper

Classes and Converting Numeric Objects Back to Primitive Numbers

Example: The following example demonstrates how primitives can be wrapped in objects and how they can be converted back to primitives.

class Convert

{ public static void main(String args[])

{ System.out.println("Converting primitive numbers to objects "+

"using constructor");

byte b=105;

Byte bObj=new Byte(b);

System.out.println(bObj);

short s=2015;

Short sObj=new Short(s);

System.out.println(sObj);

int i=32717;

Integer iObj=new Integer(i);

System.out.println(iObj);

long l=234543335565675L;

Long lObj=new Long(l);

System.out.println(lObj);

float f=3.1415f;

Float fObj=new Float(f);

System.out.println(fObj);

double d=3.1415;

Double dObj=new Double(d);

System.out.println(dObj);

System.out.println("Converting numeric objects to primitive numbers");

byte b1=bObj.byteValue();

short s1=sObj.shortValue();

int i1=iObj.intValue();

long l1=lObj.longValue();

float f1=fObj.floatValue();

double d1=dObj.doubleValue();

System.out.println(b1);

System.out.println(s1);

System.out.println(i1);

System.out.println(l1);

System.out.println(f1);

System.out.println(d1);

}

}

Output:

Converting primitive numbers to objects using constructor

105

2015

32717

234543335565675

3.1415

3.1415

Converting object numbers to primitive numbers

105

2015

32717

234543335565675

3.1415

3.1415

4. Converting Primitive Numbers to Strings using toString() static method of the corresponding Wrapper Class

Example:

class ConvertPrimitiveToString

{

public static void main(String args[])

{

System.out.println("Converting primitive numbers to String "+

"using toString() static method of corresponding wrapper class:");

byte b=105;

String str=Byte.toString(b);

System.out.println(str);

short s=303;

str=Short.toString(s);

System.out.println(str);

int i=100;

str=Integer.toString(i);

System.out.println(str);

long l=4544444444444l;

str=Long.toString(l);

System.out.println(str);

float f=3.444f;

str=Float.toString(f);

System.out.println(str);

double d=3.44444;

str=Double.toString(d);

System.out.println(str);

}

}

Output:

Converting primitive numbers to String using toString() static method of corresponding wrapper

class:

105

303

100

4544444444444

3.444

3.44444

5. Converting Numeric Objects to Strings using toString() method of the corresponding Wrapper Class

Example:

class ObjectToStringDemo

{

public static void main(String args[])

{

System.out.println("Converting object numbers to Strings using "+

"toString() method of corresponding wrapper class:");

byte b=103;

Byte bObj=new Byte(b);

String str=bObj.toString();

System.out.println(str);

short s=203;

Short sObj=new Short(s);

str=sObj.toString();

System.out.println(str);

Integer iObj=new Integer(32000);

str=iObj.toString();

System.out.println(str);

str=new Long(4544444444444l).toString();

System.out.println(str);

str=new Float(3.1444f).toString();

System.out.println(str);

str=new Double(4.1444).toString();

System.out.println(str);

}

}

Output:

Converting object numbers to Strings using toString() method of the corresponding wrapper class:

103

203

32000

4544444444444

3.1444

4.1444

6. Converting String Objects (Numeric Strings) to Numeric Objects using the static valueOf() method of the corresponding Wrapper Class

Example:

class StringToNumericObjectDemo

{ public static void main(String args[])

{ String str="30";

//String str=new String("30");

String str2="30.333";

Byte bObj=Byte.valueOf(str);

//Byte bObj1=new Byte(str2); //NumberFormatException

Short sObj=Short.valueOf(str);

Integer iObj=Integer.valueOf(str);

Long lObj=Long.valueOf("344324232432");

Float fObj=Float.valueOf("3.333");

Double dObj=Double.valueOf(str2);

System.out.println(bObj);

System.out.println(sObj);

System.out.println(iObj);

System.out.println(lObj);

System.out.println(fObj);

System.out.println(dObj);

}

}

Output:

30

30

30

344324232432

3.333

30.333

Note: All of the valueOf( ) methods throw “NumberFormatException” if the string does not contain a parsable number.

7. Converting String Objects (Numeric Strings) to Numeric Objects using Constructor of the corresponding Wrapper Class

Example:

class StringToNumericObjectDemo1

{ public static void main(String args[])

{ String str=new String("30");

//String str="30";

String str2=new String("30.333");

Byte bObj=new Byte(str);

//Byte bObj1=new Byte(str2); //NumberFormatException

Short sObj=new Short(str);

Integer iObj=new Integer(str);

Long lObj=new Long(str);

Float fObj=new Float(str2);

Double dObj=new Double(str2);

System.out.println(bObj);

System.out.println(sObj);

System.out.println(iObj);

System.out.println(lObj);

System.out.println(fObj);

System.out.println(dObj);

}

}

Output:

30

30

30

30

30.333

30.333

Note: The Above constructors throw “NumberFormatException” if the string does not contain a parsable number.

8. Converting String Objects (Numeric Strings) to Primitive Numbers using parsing method of the corresponding Wrapper Class

Example:

class StringToPrimitiveDemo

{ public static void main(String args[])

{ String str=new String("30");

//String str="30";

String str2=new String("30.333");

byte b=Byte.parseByte(str);

//byte b1=Byte.parseByte(str2); //NumberFormatException

short s=Short.parseShort(str);

int i=Integer.parseInt(str);

long l=Long.parseLong(str);

float f=Float.parseFloat(str2);

double d=Double.parseDouble(str2);

System.out.println(b);

System.out.println(s);

System.out.println(i);

System.out.println(l);

System.out.println(f);

System.out.println(d);

}

}

Output:

30

30

30

30

30.333

30.333

Note: parseXXX( ) methods throw “NumberFormatException” if the string does not contain a parsable number.

9. Constants defined in classes Double and Float

MAX_VALUE

MIN_VALUE

NaN

NEGATIVE_INFINITY

POSITIVE_INFINITY

TYPE    (The Class instance representing the primitive type double/float)

SIZE     (The number of bits used to represent a double value). Since J2SDK 1.5.

10. Other Methods in Float Class



11. Constants defined in classes Byte, Short, Integer and Long

Methods in the Double class are almost the same as methods of the Float Class; with the use of double and Double words instead of float and Float words in the previous table.

12. Constants defined in classes Byte, Short, Integer and Long

MIN_VALUE

MAX_VALUE

TYPE   (The Class instance representing the primitive type byte/short/int/long)

SIZE The number of bits used to represent a byte/short/int/long value in two's complement binary form. Since J2SDK 1.5.

13. Other Methods in Byte Class



 14. Other Methods in Short Class

Methods in the Short class are the same as methods of the Byte class, with the use of short and Short words instead of byte and Byte words in the above table.

15. Other Methods in Integer Class





16. Other Methods in Integer Class

Methods in the Long class are almost the same as methods of the Integer Class.

17. Character Class

The Character class wraps a value of the primitive type char in an object.

Constructor

Character(char value)

Constructs a newly allocated Character object that represents the specified char value.

Example: Character chObj = new Character(‘A’);

Methods

Some of the methods of Character class are described in the following table:



 Example:

class CharacterDemo1

{ public static void main(String args[])

{ char ch[]={'a', 'b','5','?','A',' '};

for(int i=0; i<ch.length;i++)

{ if(Character.isLowerCase(ch[i]))

if(Character.isDigit(ch[i]))

if(Character.isLetter(ch[i]))

if(Character.isUpperCase(ch[i]))

if(Character.isWhitespace(ch[i]))

System.out.println(ch[i]+" is lowercase");

System.out.println(ch[i]+" is a digit");

System.out.println(ch[i]+" is a letter");

System.out.println(ch[i]+" is in uppercase");

System.out.println(ch[i]+" is a whitespace");

}

System.out.println(Character.isLetter(65)); //for 'A'

System.out.println(Character.isLetter(64)); //for '@'

}

}

Output:

a is lowercase

a is a letter

b is lowercase

b is a letter

5 is a digit

A is a letter

A is in uppercase

  is a whitespace

true

false

18. Boolean Class

The Boolean class wraps a value of the primitive type boolean in an object.

18.1 Constructors


18.2 Methods of Boolean Class



Example: The Stack class in the following example represents a generalized stack as it is using an array of objects to store the elements. The StackDemo class creates three instances and uses them to store primitive data types using wrapper classes.

class Stack

{

int top = -1;

int size;

Object a[];

Stack(int size)

{

this.size = size;

a = new Object[size];

}

void push(Object x)

{

if(top == size-1)

{

System.out.println("Stack Full");

return;

}

top = top + 1;

a[top] = x;

}

Object pop()

{

if(top ==  -1)

{

return null;

}

Object x = a[top];

top = top - 1;

return x;

}

}

class StackDemo

{

public static void main(String args[])

{

Stack s1 = new Stack(10);

Stack s2 = new Stack(10);

Stack s3 = new Stack(10);

s3.push(new Integer(10));

s3.push(new Long(20L));

s3.push(new Float(13.5));

s3.push(new Double(14.5));

for(int i = 0; i < 10; i++)

{ s1.push(new Integer(i));

}

for(int i = 10; i < 20; i++)

{ s2.push(new Float(i+0.5));

}

Object x; int sum = 0;

for(int i = 0; i < 10; i++)

{ x = s1.pop(); System.out.print(x + " ");

int a = ((Integer)x).intValue();

sum = sum+a;

}

float fsum = 0;

System.out.println("\n sum: "+sum);

for(int i = 0; i < 10; i++)

{

x = s2.pop();

System.out.print(x +" ");

float f = ((Float)x).floatValue();

fsum = fsum+f;

}

System.out.println("\n sum: " + fsum);

double dsum = 0;

while((x = s3.pop()) != null)

{ System.out.print(x +" ");

if(x instanceof Integer)

if(x instanceof Long)

if(x instanceof Float)

if(x instanceof Double)

}

System.out.println("\n sum: " + dsum);

dsum= dsum + ((Integer)x).intValue();

dsum= dsum + ((Long)x).longValue();

dsum= dsum + ((Float)x).floatValue();

dsum= dsum + ((Double)x).doubleValue();

}

}

Output:

9 8 7 6 5 4 3 2 1 0

 sum: 45

19.5 18.5 17.5 16.5 15.5 14.5 13.5 12.5 11.5 10.5

 sum: 150.0

14.5 13.5 20 10

 sum: 58.0

java.lang.Object Class

1.Introduction

The Object class is at the root of all the hierarchies in Java. This class is part of the java.lang package. All classes extend the Object class, either directly or indirectly. Even if you write a simple class (i.e. it is not extending any base-class), it implicitly extends built-in Object class.

Thus the features of this class will be available in all the classes because of inheritance.

2. Important Methods in Object class

The object class defines following methods, which are inherited by all the classes.
  • public int hashCode()
  • public boolean  equals(Object obj)
  • public final Class getClass()
  • public String toString()
  • public protected void finalize() throws Throwable
  • public protected Object clone() throws CloneNotSupportedException
  • public final void wait(long timeout) throws InterruptedException
  • public final void wait(long timeout, int nanos) throws InterruptedException
  • public final void wait() throws InterruptedException
  • public final void notify()
  • public final void notifyAll()

2.1 public int hashCode()

When storing objects in hash tables, this method can be used to get a hash value for an object.

This value is guaranteed to be consistent during the execution of the program. If the objects of a class are to be maintained in hash based collections and maps of the java.util package, the class must provide appropriate implementation of the following methods from class Object:
  • hashCode()
  • equals()

As a general rules for implementing these methods a class that overrides the equals() method must also override the hashCode() method.

General contract of the hashCode() method:

(a) Consistency during execution: Multiple invocations of the hashCode() method on an object must consistently return the same hash code during the execution of an application, provided the object is not modified to affect the results returned by the equals() method.

(b) Object value equality implies hash value equality.

(c) Object value inequality places no restrictions on the hash value. If two objects are unequal according to equals() method, then the hashCode() method need not produce distinct hash code for these objects. It is strongly recommended that the hashCode() method produce unequal hash codes for unequal objects.

Note: The hash contract does not imply that objects with equal hash codes are equal. Not producing unequal hash codes for unequal objects can have an adverse effect on performance, as unequal objects will hash to same bucket, which will result in collision.

2.2 boolean equals(Object obj)

If every object is to be considered unique, then it is not necessary to override the equals() method of the Object class. This method implements object reference equality. It implements the most discriminating equivalence relation possible on objects. Each instance of the class is equal to itself.

The equals() method is usually overridden to provide the semantics of object value equality, as is the case for the wrapper classes and the String class.

2.3 final Class getClass()

Returns the runtime class of the object, which is represented by an object of the class java.lang.Class at runtime.

Example: The following example illustrates that this method can be used to get the Class object corresponding to any java Object. We can then use method of the class Class to get information about the object's class using reflection/introspection.

import java.lang.reflect.Method;

import java.lang.reflect.Field;

class DispClassInfo

{

public static void main(String args[]) throws ClassNotFoundException

{

String s = new String ("Hello");

Class c = s.getClass();

Method m[] = c.getMethods();

int l;

l = m.length;

System.out.println (".........Public Methods (" + l + ")......");

for(int i = 0; i < l; i++)

{

System.out.println (m[i]);

}

Field f[] = c.getFields();

l = f.length;

System.out.println (".........Public Fields (" + l + ")......");

for(int i = 0; i < l; i++)

{

System.out.println (f[i]);

}

m = c.getDeclaredMethods();

l = m.length;

System.out.println ("......... Declared Methods (" + l + ")......");

for(int i = 0; i < l; i++)

{

System.out.println (m[i]);

}

f = c.getDeclaredFields();

l = f.length;

System.out.println (".........Declared Fields (" + l + ")......");

for(int i = 0; i < l; i++)

{

System.out.println (f[i]);

}

}

}

Example: The previous example is modified so as to read the fully qualified class name as command line argument and then display the information about the class's methods and fields using reflection/introspection.

import java.lang.reflect.Method;

import java.lang.reflect.Field;

class DispClassInfo

{

public static void main(String args[]) throws ClassNotFoundException

{

Class c = Class.forName(args[0]);

Method m[] = c.getMethods();

int l;

l = m.length;

System.out.print();

System.out.println (".........Public Methods (" + l + ")......");

for(int i = 0; i < l; i++)

{

System.out.println (m[i]);

}

Field f[] = c.getFields();

l = f.length;

System.out.println (".........Public Fields (" + l + ")......");

for(int i = 0; i < l; i++)

{

System.out.println (f[i]);

}

m = c.getDeclaredMethods();

l = m.length;

System.out.println ("......... Declared Methods (" + l + ")......");

for(int i = 0; i < l; i++)

{

System.out.println (m[i]);

}

f = c.getDeclaredFields();

l = f.length;

System.out.println (".........Declared Fields (" + l + ")......");

for(int i = 0; i < l; i++)

{

System.out.println (f[i]);

}

}

}

2.4 String toString()

If a sub class does not override this method, it returns a textual representation of the object, which has the following format:

“<name of the class>@<hash code value of object>”

The method is usually overridden and used for debugging purposes. The method call System.out.println(Objref) will implicitly convert its argument to a textual representation using toString() method.

Example: This example demonstrates what gets displayed if we try to display object of class Box1. The object is converted to the textual representation using the toString() method of the object class.

class Box1

{ double w, h, d;

Box1(double w, double h, double d)

{ this.w=w; this.h=h; this.d=d;

}

}

class ToStringDemo1

{ public static void main(String args[])

{ Box1 b=new Box1(10,12,14);

String s="Box1 b: "+b; //concatenates box object

System.out.println(b);

System.out.println(s);

}

}

Output:

Box1@82ba41

Box1 b: Box1@82ba41

Example: This example demonstrates that if we override the toString() method in the Box1 class then the overridden method is used to convert the object to its textual representation.

class Box1

{ double w, h, d;

Box1(double w, double h, double d)

{ this.w=w; this.h=h; this.d=d;

}

public String toString()

{ return "Dimensions are "+w+" by "+h+" by "+d+".";

}

}

class ToStringDemo2

{ public static void main(String args[])

{ Box1 b=new Box1(10,12,14);

String s="Box1 b: "+b; //concatenates box object

System.out.println(b);

System.out.println(s);

}

}

Output:

Dimensions are 10.0 by 12.0 by 14.0.

Box1 b: Dimensions are 10.0 by 12.0 by 14.0.

2.5 protected void finalize() throws Throwable

It is called on an object just before it is garbage collected, so that any cleaning up can be done.

However, the default finalize() method in the object class does not do anything useful. This may be useful for releasing non-java resources but not recommended.  It is possible that finalize() method may never be called if enough memory is available and in that case resources may never be released.

2.6 protected Object clone() throws CloneNotSupportedException

New objects that are exactly the same (i.e., have identical states) as the current object can be created by the clone() method, that is, primitive values and reference values are copied. This is called shallow cloning.

A class can override the clone() method to provide its own notion of cloning. For example, cloning a composite object by recursively cloning the constituent objects is called deep cloning.

When overridden, the method in the subclass is usually declared public to allow any client to clone objects of the class.

If overriding clone() method relies on the clone() method in the Object class, then the subclass must implement the Cloneable marker interface to indicate that its objects can be safely cloned. Otherwise, the clone() method in the Object class will throw a checked CloneNotSupportedException.

Using clone() and the Cloneable interface

The clone() method generates a duplicate copy of the object on which it is called.

These are few important faces related to clone() method.

  • Only classes that implement the Cloneable interface can be cloned.
  • The Cloneable interface defines no members. It is used to indicate that a class allows a bit-wise copy ofan object (that is, a clone) to be made. If you try to call clone() on object of a class that does not implement Cloneable interface, CloneNotSupportedException is thrown.
  • Cloneable interface is an empty interface. Such an interface is called marker/tag interface.
  • When a clone is made, the constructor for the object being cloned is not called.
  • A clone is simply an exactly copy of the original. Cloning is potentially a dangerous action, because it can cause unintended side effects. For example, if the object being cloned contains a reference variable called objRef, then when the clone is made the objRef in clone will refer to the same object as does objRef in original. If the clone makes a change to the contents of the object referred to by objRef, then it will be changed for the original object, too.

Example: The following example demonstrate the use of clone() method. The CloneDemo1 class is making clone of the object of class TestClone by indirectly calling the clone method through cloneTest() method because clone() method of the object class is protected.

class TestClone implements Cloneable

{

int a;

double b;

public TestClone cloneTest() throws CloneNotSupportedException

{

}

return (TestClone) clone();

}

class CloneDemo1

{

public static void main(String a[]) throws CloneNotSupportedException

{

TestClone tc1 = new TestClone();

TestClone tc2;

tc1.a = 10;

tc1.b = 3.5;

tc2 = tc1.cloneTest();

System.out.println (tc2.a);

System.out.println (tc2.b);

}

}

Output:

10

3.5

Here, the method cloneTest() calls clone() of Object class and returns the result. Notice that the object returned by clone() must be cast into its appropriate type i.e. TestClone.

Example: In the following example the clone() method is overridden so that it can be called from code outside of its class. To do this, its access modifier must be public.

class TestClone1 implements Cloneable

{

int a;

double b;

public Object clone() throws CloneNotSupportedException

{

}

}

class CloneDemo2

{

public static void main(String a[]) throws CloneNotSupportedException

{

return super.clone();

TestClone1 tc1 = new TestClone1();

TestClone1 tc2;

tc1.a = 10;

tc1.b = 3.5;

tc2 = (TestClone1) tc1.clone();

System.out.println (tc2.a);

System.out.println (tc2.b);

}

}

Output:


10

3.5

Example: In the following example the clone() method is overridden such that it does not make use of the clone() method of the Object class. We are writing our own clone() method.

class TestClone2

{

int a;

double b;

public Object clone()

{

TestClone2 tc = new TestClone2();

tc.a = a;

tc.b = b;

return tc;

}

}

class CloneDemo3

{

public static void main(String a[])

{

TestClone2 tc1 = new TestClone2();

TestClone2 tc2;

tc1.a = 10;

tc1.b = 3.5;

tc2 = (TestClone2) tc1.clone();

System.out.println (tc2.a);

System.out.println (tc2.b);

}

}

Note: You need not declared CloneNotSupportedException and need not implement Cloneable interface if implementing your own clone() method.

Side Effects of Cloning

The side effects caused by cloning are sometimes difficult to see at first. It is easy to think that a class is safe for cloning when it actually is not. In general, you should not implement Cloneable interface for any class without good reason.

Example: This example demonstrates the side effect of cloning.

class TestShallowClone implements Cloneable

{

int a;

double b;

int c[];

public Object clone() throws CloneNotSupportedException

{

}

}

class ShallowCloneDemo

{

public static void main(String a[]) throws CloneNotSupportedException

{

return super.clone();

TestShallowClone tc1 = new TestShallowClone();

TestShallowClone tc2;

tc1.a = 10;

tc1.b = 3.5;

int c[] = new int[4];

for(int i = 0; i < 4; i++)

c[i] = i;

tc1.c = c;

for(int i = 0; i < 4; i++)

System.out.println ("tc1.c["+i+"]="+tc1.c[i]);

tc2 = (TestShallowClone) tc1.clone();

System.out.println ("tc2.a="+tc2.a);

System.out.println ("tc2.b="+tc2.b);

for(int i = 0; i < 4; i++)

System.out.println ("tc2.c["+i+"]="+tc2.c[i]);

for(int i = 0; i < 4; i++)

tc2.c[i] = i+4;;

for(int i = 0; i < 4; i++)

System.out.println ("tc2.c["+i+"]="+tc2.c[i]);

for(int i = 0; i < 4; i++)

System.out.println ("tc1.c["+i+"]="+tc1.c[i]);

}

}

Output:

tc1.c[0]=0

tc1.c[1]=1

tc1.c[2]=2

tc1.c[3]=3

tc2.a=10

tc2.b=3.5

tc2.c[0]=0

tc2.c[1]=1

tc2.c[2]=2

tc2.c[3]=3

tc2.c[0]=4

tc2.c[1]=5

tc2.c[2]=6

tc2.c[3]=7

tc1.c[0]=4

tc1.c[1]=5

tc1.c[2]=6

tc1.c[3]=7

Example: The following code eliminates the problem faced in the previous example by implementing deep cloning.

class TestDeepClone implements Cloneable

{

int a;

double b;

int c[];

public Object clone() throws CloneNotSupportedException

{

TestDeepClone tc = (TestDeepClone) super.clone();

int c[] = new int[4];

for(int i = 0; i < 4; i++)

c[i] = tc.c[i];

return super.clone();

}

}

class DeepCloneDemo

{

public static void main(String a[]) throws CloneNotSupportedException

{

TestDeepClone tc1 = new TestDeepClone();

TestDeepClone tc2;

tc1.a = 10;

tc1.b = 3.5;

int c[] = new int[4];

for(int i = 0; i < 4; i++)

c[i] = i;

tc1.c = c;

for(int i = 0; i < 4; i++)

System.out.println ("tc1.c["+i+"]="+tc1.c[i]);

tc2 = (TestDeepClone) tc1.clone();

System.out.println ("tc2.a="+tc2.a);

System.out.println ("tc2.b="+tc2.b);

for(int i = 0; i < 4; i++)

System.out.println ("tc2.c["+i+"]="+tc2.c[i]);

for(int i = 0; i < 4; i++)

tc2.c[i] = i+4;;

for(int i = 0; i < 4; i++)

System.out.println ("tc2.c["+i+"]="+tc2.c[i]);

for(int i = 0; i < 4; i++)

System.out.println ("tc1.c["+i+"]="+tc1.c[i]);

}

}

Output:

tc1.c[0]=0

tc1.c[1]=1

tc1.c[2]=2

tc1.c[3]=3

tc2.a=10

tc2.b=3.5

tc2.c[0]=0

tc2.c[1]=1

tc2.c[2]=2

tc2.c[3]=3

tc2.c[0]=4

tc2.c[1]=5

tc2.c[2]=6

tc2.c[3]=7

tc1.c[0]=0

tc1.c[1]=1

tc1.c[2]=2

tc1.c[3]=3

2.7 Methods useful in multi-threaded environment

In addition to methods discussed above, Object class provides support for thread communication in synchronized code through the following methods:

final void wait()

Causes current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object.

final void wait(long timeout) throws InterruptedException

Causes current thread to wait until either another thread invokes the notify() method or the notifyAll() method for this object, or some other thread interrupts the current thread, or the specified amount of time has elapsed.

final void wait(long timeout, int nanos) throws InterruptedException


Causes current thread to wait until either another thread invokes the notify() method or the notifyAll() method for this object, or some other thread interrupts the current thread, or the certain amount of time has elapsed.

final void notify()


Wakes up a single thread that is waiting on this object's monitor.

final void notifyAll()

Wakes up all threads that are waiting on this object's monitor. A thread waits on an object's monitor by calling one of the wait methods.

A thread invokes these methods on the object whose lock it holds. A thread waits for notification by another thread.

Friday, 19 June 2015

Java StringBuffer Class

StringBuffer is a peer class of String that provides much of the functionality of Strings. In contrast to String, StringBuffer represents growable and writeable character sequences.

StringBuffer may have characters and substrings inserted in the middle or appended to the end.

StringBuffer will automatically grow to make room for such additions and often has more characters pre-allocated than are actually needed, to allow room for growth.

Few important point related to StringBuffer class

  • StringBuffer is an Object like String.
  • StringBuffer class is also final like String class.
  • StringBuffer objects are mutable (can be modified) unlike String objects.

Constructors of StringBuffer Class


Methods of StringBuffer Class



Example:

class SBDemo1

{ public static void main(String args[])

{ StringBuffer sb1 = new StringBuffer();

System.out.println("sb1: length: "+sb1.length() + " capacity: " + sb1.capacity());

StringBuffer sb2 = new StringBuffer(100);

System.out.println("sb2: length: "+sb2.length() + " capacity: " + sb2.capacity());

StringBuffer sb3 = new StringBuffer("Hello");

System.out.println("sb3: length: "+sb3.length() + " capacity: " + sb3.capacity());

sb1.ensureCapacity(200);

System.out.println("sb1: length: "+sb1.length() + " capacity: " + sb1.capacity());

sb3.setLength(10);

System.out.println("sb3: length: "+sb3.length() + " capacity: " + sb3.capacity());

System.out.println("sb3: "+sb3);

sb3.setLength(3);

System.out.println("sb3: length: "+sb3.length() + " capacity: " + sb3.capacity());

System.out.println("sb3: "+sb3);

}

}

Output:

sb1: length: 0 capacity: 16

sb2: length: 0 capacity: 100

sb3: length: 5 capacity: 21

sb1: length: 0 capacity: 200

sb3: length: 10 capacity: 21

sb3: Hello

sb3: length: 3 capacity: 21

sb3: Hel

append() Method

It has overloaded versions for all the built-in types and for Object. These are the few of its form:

public StringBuffer append(char c)

public StringBuffer append(String str)

public StringBuffer append(boolean b)

public StringBuffer append(Object obj)

public StringBuffer append(int num)

public StringBuffer append(double

public StringBuffer append(char[] str)

public StringBuffer append(StringBuffer sb)

String.valueOf() method is called for each parameter to obtain its String representation. The result is appended to the current StringBuffer object. The buffer itself is returned by each version of append(). This allows subsequent calls to be chained together.

Note: If null string is appended then “null” gets appended.

insert() Method

The insert() method inserts one string into another. It is overloaded to accept values of all the simple types, plus Strings and Objects. Like append() method, it calls String.valueOf() method to obtain the string representation of the argument passed to it. This string is then inserted into the invoking StringBuffer object. These are the few of its form:

public StringBuffer insert(int offset, char c)

public StringBuffer insert(int offset, int c)

public StringBuffer insert(int offset, long l)

public StringBuffer insert(int offset, char[] str)

public StringBuffer insert(int offset, double d)

public StringBuffer insert(int offset, float f)

public StringBuffer insert(int offset, String str)

public StringBuffer insert(int offset, Object obj)

Example: The following example illustrates some of the methods discussed above.

class SBDemo2

{ public static void main(String args[])

{ String s; int a=42;

StringBuffer sb=new StringBuffer(40);

s=sb.append("a= ").append(a).append("!").toString();

System.out.println(s);

StringBuffer sb1=new StringBuffer("I Java!");

sb1.insert(2, "like ");

System.out.println(sb1);

System.out.println("Reverse of "+sb1+" is: "+sb1.reverse());

}

}

Output:

a= 42!

I like Java!

Reverse of I like Java! is: !avaJ ekil I

Monday, 15 June 2015

Java String important methods

Character Extraction Methods

The String class provides a number of ways in which characters can be extracted from a String object. Although the characters that comprise string within a String object cannot be indexed as if they were a character array, many of the String methods employ an index (or offset) into the string for their operation. Like arrays, the string indexes begin at zero.


Example: The following example illustrates the use of character extraction methods discussed above:

class ExtractionDemo

{ public static void main(String args[])

{ String s = "This is a Demo of character extraction methods";

char c = s.charAt(10);

System.out.println("Character at position 10: " + c);

char carray[] = s.toCharArray();

System.out.print("Character Array: ");

for(int i=0; i<carray.length; i++)

System.out.print(carray[i]);

System.out.println();

byte b[] = s.getBytes();

System.out.print("Byte Array: ");

for(int i=0; i<b.length; i++)

System.out.print((char) b[i]);

System.out.println();

int start = 10; int end = 14;

char buf[] - new char[end-start];

s.getChars(start, end, buf, 0);

System.out.println(buf);

}

}

Output:


Character at position 10: D

Character Array: This is a Demo of character extraction methods

Byte Array: This is a Demo of character extraction methods

Demo

String Comparison Methods



The regionMatches() method compares a specific region inside a styring with another specific region in another string. Thre is an overloaded form that allows you to ignore case in such comparisions.

For both versions, startIndex specifies the index at which the region begins within the invoking string object. The string being compared is specified by str2. The index at which the comparison will starts within the str2 is specified by str2StartIndex. The length of the substring being compared is passed in len.

Example: The following example illustrates the use of regionMatches() method.

class Region

{ public static void main(String args[])

{ String s="Yahoo!";

String s2="yahoo.com";

System.out.println(s.regionMatches(0,s2,0,5));

System.out.println(s.regionMatches(true,0,s2,0,5));//ignore case

System.out.println(s.resionMatches(-1,s2,-1,5));

}

}

Output:

false

true

false

Example: The following example illustrates the use of compareTo() method.

class CompareToDemo

{ public static void main(String args[])

{ String s="yahoo!";

String s2="Yahoo!";

String s3="yahoo";

System.out.println(s.compareTo(s2));

System.out.println(s.compareToIgnoreCase(s2));//ignore case

System.out.println(s.compareTo(s3));

}

}

Output:

32

0

1

startsWith( ) and endsWith( )


Example: The following example illustrates the use of startsWith() and endsWith() methods.

class ComparisonDemo

{ public static void main(String args[])

{ String name="Rahul Jain Januthariya";

System.out.println(name.startsWith("Rahul"));

System.out.println(name.startsWith("rahul"));

System.out.println(name.endsWith("Januthariya"));

System.out.println(name.startsWith("Jain",7));

}

}

Output:

true

false

true

true

The equals( ) v/s = =

The equals() method compares the characters inside a String object. The == compares two object references to see whether they refer to the same instance.

String Search Methods

String class provides methods that allow you to search a string for a specified character or substring. In all cases, methods return the index at which the character or substring is found or –1 on failure.


Methods for String Modification

Because String objects are immutable, whenever you want to modify a string, you must either copy it into a StringBuffer or use one of the following string methods, which will construct a new copy of the string with your modifications.





Note: The substring() methods throw IndexOutOfBoundsException if the beginIndex is negative, or endIndex is larger than the length of this String object, or beginIndex is larger than endIndex.




Java Special String operations

1. String Literals

For each String literal in your program java automatically constructs String object. Thus, you can use a string literal to initialize a String object.

String s = “abc”;

Because a String object is created for every string literal, you can use a string literal at any place you can use a String object.

For example, you can call methods directly on a quoted string as it uses an object reference.

System.out.println(“abc”.length());

2. String Concatenation


In general, Java does not allow operators to be applied to String objects. The one exception to this rule is + operator, which concatenates two strings producing a String object as a result.

Example: The reference of the concatenated string “Rahul Jain Januthariya” will be stored in the reference variable name.

String name = “Rahul” + “ ”  +  “Jain”  +  “ ” + “Januthariya”

String Concatenation with other data types

If a string is concatenated with any data of type other than the string, the compiler converts the other operand (non-string) to its string equivalent.

Example:

String s = “four: “+ 2 + 2 ; System.out.println(s);

Output: four:22

String Conversion and toString( )

When Java converts data into its String representation during concatenation, it does so by calling one of the overloaded versions of the String conversion method valueOf() defined by String class. The valueOf() is a static method overloaded for all simple types and for type Object.

For the simple types, valueOf() returns string that contains the human-readable equivalent of the value with which it is called. For objects, valueOf() calls the toString() method on the object.

Every class inherits toString(), because it is defined by the Object class. However, the default implementation of the toString() is seldom sufficient. It displays name of the class followed by symbol “@” and then object-id (e.g. Box@ab1232), which is normally of no use. For most important classes that you create, you will want to override toString() and provide your own string representations.

You can do so by overriding the toString( ) method:

String toString()

Example:

class Box

{ double w, h, d;

Box( double w, double h, double d)

{ this.w=w; this.h=h; this.d=d;

}

public String toString()

{ return "Dimensions are "+w+" by "+h+" by "+d+".";

}

class ToStringDemo1

{ public static void main(String args[])

{ Box b=new Box(10,12,14);

String s="Box b: "+b; //concates box object

System.out.println(b);

System.out.println(s);

}

}

Output:

Dimensions are 10.0 by 12.0 by 14.0.

Box b: Dimensions are 10.0 by 12.0 by 14.0

Note: If toString() is not overridden, the output of this program will be something like:

Box@b8df17

Box b: Box@b8df17

Java String Constructors

The class String supports many constructors to create String objects. The simplest way to

construct a string is to assign a literal value to a String type variable:

String str = "This is a string";

The above statement will create a string object with the specified contents.

Some of the commonly used constructors are described below:

String()


Initializes a newly created String object so that it represents an empty character sequence:

String str = new String();

String (String str)

Initializes a newly created String object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string.

Examples:

String str = new String("This is a string");

String str1 = new String(str);

The string str1 is a copy of string str. Although contents are same but str and str1 point to different string objects.

String(char[] value)

Allocates a new String so that it represents the sequence of characters currently contained in the character array argument.

Example: String str in the following example will hold “abc”.

char cr[] = { ‘a’,’b’,’c’};

            String str = new String (cr);

String(char value[], int offset, int count)

Allocates a new String that contains characters from a sub-array of the character array argument.

Example: String str in the following example will hold “cde”.

char cr[] = { ‘a’,’b’,’c’,’d’,’e’,’f’ };

            String s = new String (cr,2,3);

String(byte b[])

Constructs a new String by decoding the specified array of bytes using the platform's default charset.

String(byte[]  b, int offset, int length)

Constructs a new String by decoding the specified subarray of bytes using the platform's default charset.

Even though Java's char type uses 16 bits to represent the Unicode character set, the typical format for strings on the Internet uses arrays of 8-bit bytes constructed from the ASCII character set. Because 8-bit ASCII strings are common, the String class provides constructors that initialize a string when given a byte array. In each of the above constructors the byte to character
conversion is done by using the default character encoding of the platform.

Example: The following example illustrates the use of the constructors, which convert byte array into string.

class SubStringCons

{ public static void main(String args[])

{ byte ascii[] = { 65,66,67,68,69,70 };

String s = new String (ascii);

System.out.println(s);

String s1 = new String (ascii, 2, 3);

System.out.println(s1);

}

}

Output:

ABCDEF

CDE

Java String introduction

The classes String and StringBuffer are part of the java.lang package.

(i) String in Java is an Object

String is a sequence of characters. But, unlike many other languages that implement strings as character arrays, Java implements strings as objects of type String.

Implementing strings as built in objects allows java to provide a full complement of features that make string handling convenient. Also string objects can be constructed a number of ways, making it easy to obtain a string when needed.

(ii) Strings are Immutable

Strings are immutable i.e. you cannot change the string after creation. However, a variable declared as a String reference can be changed to point at some other String object at any time.

You can still perform all types of string operations. Each time you need an altered version of an existing string, a new string object is created that contains the modifications. The original string is left unchanged. This approach is used because fixed, immutable strings can be implemented more efficiently than changeable ones. For those cases in which a modifiable string is desired, there is a companion class called StringBuffer, whose objects contain strings that can be
modified after they are created.

(iii) String class is final

Both String and StringBuffer classes are final. This allows certain optimizations that increase performance of common string operations as discussed in the previous chapter on modifiers.

Java modifiers for class members

  • static
  • final
  • abstract
  • synchronized
  • native
  • transient
  • volatile
1. static modifier

The static members belong to the class in which they are declared, and are not part of any instance of the class. Depending on the accessibility modifiers of the static members in a class, client can access these by using the class name or through object references of the class.

static variables (also called class variables)

These variables only exist in the class they are defined in. When the class is loaded, static variables are initialized to their default values, if no explicit initialization expression in specified.

The static member variables are often used when tracking global information about the instances of a class.

static methods

These are also known as class methods. A static method in a class can directly access other static members in the class. It cannot access instance (i.e. non-static) members of the class, as there is no notion of an object associated with a static method.

However, note that a static method in a class can always use a reference of the class’s type to access its members regardless of whether these members are static or not.

A typical static method might perform some task on behalf of the whole class and/or objects of the class.

An instance in a subclass cannot override a static method in the superclass. The compiler will flag this with an error (means a static method in super class cannot be overridden by non static methods in subclass). A static method is class specific and not part of any object, while overriding, methods are invoked on the behalf of objects of the subclass. However, a static

method in a subclass can hide a static method in the superclass.

Methods declared as static have several restrictions:

  • They can only call other static methods.
  • They can only access static data members
  • They cannot refer to this or super in anyway

static initialization block

A java class can have one or more static initialization block. The syntax of the static initialization block is as follows:

static

{

code

}

A static initialization block can be thought of as a static method, which is invoked implicitly/automatically as soon as the class is loaded.

The static block can be useful in the following situations:

  • Dynamic initialization of static variables.
  • For performing one time activity at the time of loading class. For example, loading jdbc driver class.
  • Loading small database/configuration files in Hashtable, HashMap, Properties etc.

2. final modifier

The modifier final can be used with
  • local variables
  • instance variables/data members
  • static variables/data members
  • instance methods

2.1 final variables

A final variable is normally initialized at the time of declaration and its value cannot be modified after assigning once. Here are few important points related to final variables:
 
  • A final variable is a constant, despite being called a variable. Its value cannot be changed once it has been initialized. This applies to instance, static and local variables, including parameters that are declared final.

  • The final is the only modifier applicable to local variables or formal parameters.
  • A final variable of a primitive data type cannot change its value once it has been initialized.
  • A final variable of a reference type cannot change its reference value once it has been initialized, but the state of the object it denotes can still be changed.
  • Normally a final variable is initialized at the time of declaration but it is not must. Such a final variable is also called blank final variable, and must be initialized once before it is being used.
  • The final static variables are commonly used to define named constants, for example Integer.MAX_VALUE, which is the maximum int value.

2.2 local final variables

Example: The following example illustrates that local final variable can be left blank as discussed above but must be initialized before first use. The variable x is initialized just before displaying its value on the monitor.

class FinalTest //makes use of blank final

{ public static void main(String args[])

{ final int x;//initialization at declaration time not must

x = 50;

System.out.println(x);

}

}

Output:

50

The following program will not compile as final variable is initialized after first use.

class FinalTest

{ public static void main(String args[])

{ final int x; //blank final

System.out.println(x);

x = 50;

}

}

The following program will not compile as final variable is initialized twice.

class FinalTest

{ public static void main(String args[])

{ final int x;

x = 50;

System.out.println(x);

x = 60;

}

}

2.3 instance final variables

An instance final variable can be left blank but must be initialized before obtaining a reference of an object of the class containing final variable. So if we do not initialize at the time of declaration then the other places at which final variables can be initialized are:

  • Constructor

  • Initialization block

Example: The following program will not compile, as final variable is not initialized. The concept of initialization by default value is not applicable to final variables as they cannot be modified after initialization.

class FinalTest

{ final int x;//No default initialization for final instance variables

}

class MyClass

{

public static void main(String args[])

{ FinalTest f=new FinalTest();

}

}

Output: (Compile time error): variable x might not have been initialized

Example: The following program will also not compile, as final variable is initialized after obtaining a reference.

class FinalTest

{ final int x;

}

class MyClass

{ public static void main(String args[])

{ FinalTest f=new FinalTest();

System.out.println(f.x);

f.x = 10;

System.out.println(f.x);

}

}

Example: The following example illustrates that a blank final instance variable can be initialized in the constructor.

class FinalTest

{ final int x;

public static void main(String args[])

{ FinalTest f = new FinalTest();

}

FinalTest()

{ x = 10;

}

}

Output: 10

System.out.println(f.x);

Example: The following program illustrates that a blank final variable can be initialized with a dynamic value and can be referred with this keyword. So different objects of the same class can have different values of the final variable.


class FinalTest

{ final int x;

public static void main(String args[])

{ FinalTest f = new FinalTest(20);

}

FinalTest(int x)

{ this.x = x;

}

}

Output: 20

System.out.println(f.x);

Example: The following program illustrates that a final instance variable can be initialized in a initialization block.

class FinalTest

{ final int x;

public static void main(String args[])

{ FinalTest f = new FinalTest();

}

{

}

}

Output: 30

Initialization block

A java class can have one or more initialization blocks. The syntax of the initialization block is as follows:

{

code

}

An initialization block can be thought of as a constructor, which is invoked
implicitly/automatically as soon as the object is created. In fact if a class contains initialization

System.out.println(f.x);

x = 30;

blocks then they are executed in the order of definition from top to bottom before any constructor.

The initialization block can be useful in the following situations:

  • Dynamic initialization of instance variables.

  • For defining code which is common to all constructors. This will increase the code reusability and reduce maintenance.

2.4 static final variables

A static final variable can be left blank but must be initialized before class is available to the program. So if we do not initialize at the time of declaration then the only place at which static final variable can be initialized is:

  • static Initialization block
Example: The following example illustrates that the blank static final variable can be initialized in the static block.

class FinalTest

{ static final int x;

public static void main(String args[])

{

}

static

{

}

}

Output:

40

System.out.println(FinalTest.x);

x = 40;

2.7.2.5 final methods

  • A final method in a class is complete (i.e. has an implementation) and can not be overridden in any subclass. Subclasses are thus restricted in changing the behavior of the method.
  • The compiler is able to perform certain code optimizations for final methods, because certain assumptions can be made about such members. When a non-final method is invoked, the run time system determines the actual class of the object, binds the method invocation to the correct implementation of the method for that type, and then invokes the implementation. In case of a final method we are sure that sub-class can not override the method so the binding is done at the compile time as in case of private and static methods, which would definitely improve the performance.

  • In case of a final method the compiler may replace an invocation with the actual body of the method like Macro. This mechanism is known as ‘inlining’. In C++, we have the option of declaring a function as inline (although final decision is taken by the compiler) but in Java, the compiler takes the decision.

3. abstract modifier

The abstract modifier can be used only with instance methods. An abstract method does not have an implementation, that is, no method body is defined for an abstract method, only the method prototype is provided in the class definition. Its class is also abstract (i.e., incomplete) and must be explicitly declared as abstract. Subclasses of an abstract class must then provide the method implementation; otherwise, they are also abstract.

Here are some important points related to abstract methods:

  • An abstract method cannot be declared private. This is obvious as we can not override a private method, while in case of an abstract method body is always provided in the sub-class by over-riding the abstract method.

  • Only a non-static/instance method can be declared abstract since static methods cannot be overridden, declaring an abstract static method would make no sense and will result in compilation error.

  • Only an instance method can be declared abstract since static methods cannot be overridden, declaring an abstract static method would make no sense and will result in compilation error.

  • A final method cannot be abstract and vice-versa.

  • The keyword abstract cannot be combined with any non-accessibility modifiers for methods.

  • Methods specified in an interface are implicitly abstract, as only the method prototypes are defined in an interface.

4. synchronized modifier

The synchronized keyword can be used with methods and code blocks.

Several threads can execute simultaneously in a program. They might try to execute several methods on the same object simultaneously. If it is desired that only one thread at a time can execute a method in the object, the methods can be declared synchronized. Their execution is then mutually exclusive among all threads. At any given time, at most one thread can be executing a synchronized method on an object. This discussion also applies to static synchronized methods of a class. The detailed discussion is available in the chapter on multi-threading.

Example:

Suppose you have two threads that are responsible for updating a bank balance, called threads A and B. Suppose also that the account has $100 in it. Now simultaneously, thread A tries to deposit $50 in the account, while thread B tries to deposit $75. Both threads proceed to query the account balance. They both find it to be $100. Each of them independently, adds its deposit to the old sum and sets the new balance accordingly. If thread A finishes last, the account contains

$150. If thread B finishes last, the account balance is $175. Of course, neither of these new figures is correct. The account should have $225 in it (100+50+75). The problem is that both threads tried to execute the same code (querying and changing the balance) at the same time.

This is exactly the scenario that the synchronized keyword can prevent.

The synchronized modifier does not apply to classes or member variables.

5. native modifier

The native modifier can refer only to methods. Like the abstract keyword, native indicates that the body of a method is to be found elsewhere. The body of a native method is entirely outside the JVM, in a library.

Native code is written in a non-java language, typically C or C++, and compiled for a single target machine type. Thus Java’s platform independence is violated.

People who port Java to new platforms implement extensive native code to support GUI components, network communication, and a broad range of other platform-specific functionality.

However, it is rare for the application and applet programmers to need to write native code.

6. transient modifier

Objects can be stored using serialization. Serialization transforms objects into an output format that is conducive for storing objects. Objects can later be retrieved in the same state as when they were serialized, meaning that all fields included in the serialization will have the same values as at the time of serialization. Such objects are said to be persistent. A field can be specified as
transient in the class declaration, indicating that its value should not be saved when objects of the class are written to persistent storage.

Example:

class Experiment implements Serializable

{ transient int currentTemperature; //transient

double mass; //persistent value

}

Specifying the transient modifier for static variables is redundant and therefore, discouraged. The static variables are not part of the persistent state of a serialized object.

7. volatile modifier

During execution, compiled code might cache the values of fields for efficiency reasons. Since multiple threads can access the same field, it is vital that caching is not allowed to cause inconsistencies when reading and writing the value in the field.

The volatile modifier can be used to inform the compiler that it should not attempt to perform optimization on the field, which could cause unpredictable results when the field is accessed by multiple threads.

Monday, 8 June 2015

Java Other modifiers for interface members

Other modifiers for data members

Besides the visibility modifier public, we can also use modifiers static and final. Although we can use these modifiers but it is redundant as all data members are implicitly public, static and final.

Other modifiers for methods

Besides the visibility modifier public, we can also use modifier abstract. Although we can use abstract modifier but it is redundant as all methods are implicitly public, and abstract.

Java Other modifiers for top-level interfaces

(a) abstract

This is the only modifier other than visibility modifiers, which can be used with interface.

Interfaces just specify the method prototypes and not any implementation: they are, by their nature, implicitly abstract (i.e. they cannot be instantiated). We can declare an interface as abstract but it is redundant as interface is always abstract.