Learn Java Basics Concepts

Java Beginners Guide: Generics 1.5 tutorial in java with Example programs

The main objectives of generics are to provide type safety and resolve type casting problems.
 Case 1: Type Safety
Arrays are type safe that is we can give the guarantee for the type of elements present inside array.
For example:
If our program requirement is to hold only string type of objects we can choose string array. By mistake tying to add any type of objects we will get compile error.
String [] s=new String [10000];
S[0]=”krishna”;
S[1]=”Ravi”;
S[2]=new Integer(10); ce:incompatible types found java.lang.Integer required Java.lang.string
S[3]=”shiva”;
Hence String array contain only string type of objects due to this we can give the guarantee for type of elements present inside array. Hence arrays are safe to use with respect to type that is arrays are type safe.
But collections are not type safe that is we can not give the guarantee for type of elements present inside collections.
For Example:
If our program requirement is to hold only string type of objects and we choose array list. by mistake if we are trying to add any other type of object we won’t get any compile error but the program may fail at run time.
ArrayList l=new ArrayList()
l.add(“durga”);
l.add(“ravi”);
l.add(new Integer(10));
….
….
String name1=(String)l.get(0);
String name1=(String)l.get(1);
String name1=(String)l.get(2);wrong
RE: ClassCastException
Hence we cannot give the guarantee for type of elements present inside collection due to this collections are not safe to use with respect to type that is collections are not type safe.

Case 2: Type casting
In the case of array at the time of retrieval, it is not required to perform type casting there is guarantee for the type of elements for type of elements present inside collection.
Arraylist l=new Arraylist();
l.add(“john”);
---------------------------------
String name1=l.get(0); ce: incompatible type  found: java.lang.object required :java.lang.String
String name1=(String)l.get(0); type casting is mandatory
Hence type casting is a bigger headache in collection.
To overcome above of collection sun people introduced generics concept in 1.5 version. Hence the main objectives of generics are:
1.       To provide type safety
2.      To resolve type casting problems
 Part :2
 For example:
To hold only String type of objects we can create generic version of arraylist object as follows.
Al<String> l=new Al<String>(); for this arraylist we can add only string type of objects by mistake if we are trying to add any other type then we will get compile time error.
l.add(“john”);
l.add(“joy”);
l.add(new Integer(10)); ec: error
l.add(“johnson”);
Hence throw generics we are getting type safety.
At the time of retrieval we are not required to perform type casting.
Al<String> l=new Al<String>();
l.add(“john”);
----------------
String name1=l.get(0)
Hence throw generics we can solve type casting problem.
Al l=new Al();
Al<String> l=new Al<String>();

1.       Non generic version of Al object
2.      For This we can type of object and hence it is not type safe
3.      At the time of retrieval, Type casting  is required










1.       It is generic version of arraylist object
2.      For this we can add string type of object and It is type safe
3.      At the time of retrieval we are not required to perform Type casting.

Coclusion 1:
Polymorphism concept applicable only for base type but not for parameter type (usage of parent reference to hold child object is concept of polymorphism).
Al<String> l=new Al<String>();
List<String> l=new Al<String>();
Collection<object> l=new Al<String>(); ce: incompatible type found al<string> required al<object>.
Conclusion 2:
For the type parameter any class or interface name but not primitive if you are trying provide primitive then we will get compile time error.
Al<int> x=new Al<int>();
Ct error:unexpected type found:int required: reference.

Generic class:
 Until 1.4 version in generic version of array list class is declare as follows:
Class Arraylist{
Add(object o)
Object get(int index)
}
The argument 2 add() method is object and hence we can add any type of object to the array list due to this we are missing type safety.
The return type of get() method is object. Hence at time of retrieval we have to perform type casting.
But in 1.5 version a generic version array list class is declare as follows:
Class Al<T>// t is type parameter
{
Add(T A)
T  get(int index)
}
Based on our run time requirement T will be replaced with our provided type.
For Example:
To hold only String type of objects a generic version of array list object can be created as follows:
Al<String> l=new Al<String>();for this requirement compiler consider version of array list class is as follows:
Class Al<String>
{
Add(String s)
String get(int index)
}
The argument 2 add() method is String type hence we can add only string type of objects by mistake if trying to add other type we will get compile time error.
l.add(“john”);
l.add(new Integer);
CT error: cannot find symbol; symbol method add(java.lang.integer); location class al<String>
Hence through we are getting type safety.
The return type of get() method is String and hence at the time of retrieval we are not requiring type casting.
String name1=l.get(0);//type casting is not required.
 In generic we are associating a type parameter to the class such type of parameterized classes or nothing but generic classes or template classes.
Based on our requirement we can define our own generic classes also.
Syntax:
Class Account{

}
Account<Gold> a1=new Account<Gold>();
Account<platinum> a2=new Account<platinum>();

Example: program here
Class Gen<T>
{

}
{
}

What is bounded type? How to defined bounded type?

Bounded Types
We can bound the type parameter for particular range by using extends keyword such types are called bounded types.
Class Test<T>{
}
As the parameter we can pass any type there are no restrictions and hence it is unbounded type.
Test<Integer> t1=new Test<Integer>();
Test<String> t2=new Test<String>();
Syntax for bounded type:
Class Test<T entends X>

X can be either class or interface if X is a class then as the parameter we can pass either X type or child classes.
If X is an interface then as the type parameter we can pass X type or its implementation classes.
Class Test<T extends Numbers>
{
}
Test<Integer> t1=new Test<Integer>(); it is right
Test<String> t1=new Test<String>(); this is wrong
CT error: type parameter java.lang.String is not within its bound.

Class Test<T extends Runnable>
{
}
Test<Runnable> t1=new Test<Runnable>();
Test<Thread> t2=new Test<Thread>();
Test<Integer> t3=new Test<Integer>();//this is wrong
CT error: type parameter java.lang.Integer is not within its bound.

We can define bounded type even in combination also
Class BoundedDemo<T extends Number & Runnable>
{
}
As the type parameter we can take anything which should be child class of Number and should implements Runnable interface.

Class BoundedDemo<T extends Runnable & Comparable> this is right
Class BoundedDemo<T extends Number & Runnable & Comparable>this is right
Class BoundedDemo<T extends Runnable & Number> this is wrong because
We have to take class first followed by interface next.
Class BoundedDemo<T extends Number & Thread> this is wrong because
We can not extends more than one class simultaneously.

Note 1: we can define bounded type only by using extends keyword and we cant use implements and super keywords but we can replace implements keyword purpose with extends keyword.
Class Testdemo<T extends Number>{}this is right use
Class Testdemo<T implements Runnable>{}this wrong
Class Testdemo<T extends Runnable>{}this is right use
Class Testdemo<T super String>{}this is wrong

Note: 2
As the type parameter ‘T’ we can take any valid java identifier but it convention to use ‘T’.
Class Test<T>
Class Test<X>
Class Test<A>
Class Test<John>
These are right syntaxes.

Note 3:
Based on our requirement we can declare any number of type parameters and all these type parameters should be separated with ‘,’ .
Class Test<A,B>{}
Class Test<X,Y,Z>{}
Class HashMap<k,v>//k is key type, v is value type{}
HashMap<Integer, String> h=HashMap<Integer,String>();

Generics methods and wild card character (?)
 M1(Al<String> l)
1.       We can call this method by passing array list of only string type.
2.      But within the method , we can add only string type of objects to the list by mistake if trying to add any other type then we will get compile time error.
Example:
1.      M1(Al<String> l)
{
l.add(A);
l.add(null);
l.add(10);//this is wrong we get error
}

2.     M1(Al<?> l)

1.       We can call this method by passing array list of any type.
2.      But within the method, we cannot add anything to the list accept null because we do not know type exactly.
3.      Null is allowed because valid value for any type.
4.      This type of method are best suitable for read only operation.
M1(Al<?> l)
{
l.add(10.5) this is invalid
l.add(“A”);this is invalid
l.add(10);this is invalid
l.add(null);this is valid
}
3.     M1(Al<? extends X> l)

1.       X can be either class or interface
2.      If x is a class then we can call this method by passing array list of either X type or its child classes.
3.      If X is an interface then we can call this method by passing array list either x type or implementation classes.
4.      But within the method we can add any thing to the list expect null because we don’t know the type Exactly.
5.      This type of methods also best suitable for read only operation.

4.      M1(Al<? super X) l)

1.       X can be either class or interface if X is class then we can call this method by passing array list of either x type or its super classes.
2.      If X is an interface then we can call this method by passing array list of either X type or super class of implementation of class of X.
Hint: Object—Thread-----Runnable
3.      But within the method, we can add X type of objects and null to the list.

Al<String> l=new Al<String>();
Al<?> l=new Al<String>();
Al<?> l=new Al<Integer>();
Al<? extends Numbers> l=new Al<Integer>();
Al<? extends Numbers> l=new Al<String>();//this is invalid; incompatible type error
Al<? super String> l=new Al<Object>();
Al<?> l=new Al<?>(); //this is invalid; unexpected type error
Al<?> l=new Al<? extends Numbers();//this is invalid; unexpected type error.

We can declare type parameter either at class level or method level.

Declaring Type Parameter at class level
Class Test<T>
{
We can use ‘T’ within this class based on our requirement.
}
Declaring Type Parameter at method level                     
We have to declare type parameter just before return type.
Class Test
{
Public <T>void m1(T ob)
{
We can use ‘T’ anywhere within the method based on our requirement.
}
}

We can define bounded type even method level also
Public <T> void m1()
<T extends Number>
<T extends Runnable>
<T extends Number & Runnable>
<T extends Comparable & Runnable>
<T extends Number & Comparable & Runnable>
<T extends Runnable & Number>here, first we have to take class and then interface
<T extends Number & Thread> here, we can’t extend more than on class.

Communication with Non Generic Code:
If we send Generic object to Non Generic area then it starts behaving like non object. Similarly if we send non generic object to generic area then its start behaving like generic object that is the location in which object present based on that behavior will be defined.
Example: program here
The main purpose to provide type safety and to resolve type casting problem. Type safety and type casting both applicable at compile time. Hence generic concept also applicable only at compile time but not at run time. At time of compilation has last step generic syntax will be removed and hence for the jvm, generic syntax won’t be available.

Hence the following declarations are equal.
Al   l=new Al<String>();
Al   l=new Al<Integer>();
Al   l=new Al<Double>();
Al   l=new Al();

Example:
Al l=new Al<String>();
{
l.add(10);
l.add(10.5);
l.add(true);
System.out.println(l);
}

The following declarations are equal:
Al<String> l=new Al<String>();
Al<String> l=new Al();
For this array list object we can add only string type of objects.
   
Generic Compile Time
1.       Compile code normally by considering generic syntax.
2.      Remove generic syntax
Compile once again resultant code
Example:
Class Test
{
Public void m1(Al<String> l){}
Public void m1(Al<Integer> l){}
}
Generic concept has some disadvantages are there that why the generic concept removed in java
Error: name cash: both methods have same erasure.


Tag : Core Java
0 Komentar untuk "Java Beginners Guide: Generics 1.5 tutorial in java with Example programs"

Featured Content

Back To Top