The main Idea behind Generics is to pass Type parameter along with Implementation Itself.
Ex:
method(Integer x){
//...
}
this method only accepts Integer param.
Now let say If we need to create Our Method Generic enough that users of method can pass types also.
Something like :
method(T x){
//...
}
Now here T depends on User type.
Let say :
User #1
Integer x = new Integer(5);
method(x);
User #2
String y = new String("abc");
method(y);
So our method is generic enough to consume any Input Argument Type.
We will discuss this appraoch more .
The Other approach is for method to have Object type input parameter.
method(Object x){
//...
}
Now this approach is good to certain extend.
Observations :
a)Since all non primitive types are subclass to Object, so client with non-primitive types can easily use method.
Integer x = new Integer(5);
method(x);
String y = new String("abc");
method(y);
Both these will work like a charm.
b)Problem arises when storing elements in collection of any Type just like List<Object>
Let say we have method :
methodList(){
List strList = new ArrayList();
strList.add("abc");
strList.add("def");
//Lets assume list has two elements.
Iterator iter = list.iterator();
while (iter.hasNext()) {
String str = (String)iter.next(); //We need to explicitly Downcast, Since List will return Object element.
System.out.println(str);
}
//Now we need to add one more element, which is Integer.
Integer ints = new Integer(5);
strList.add(ints);
//If we do
String str = (String) strList.get(2);
//This will throw ClassCastException : which means element is getting casted to incompatible Type and throw ClassCastException at RunTime.
}
So, Upcasting is Implicit, Because all non Primitive types are Subclasses Of Object.which can be done easily.
But in case of Downcasting, Programmer needs to take care of when to Downcast and Correct Type to Downcast.
3)We can use instance Of while doing downcast, but again its a too much to do that.
Maintaining each type and its associated if-else condition is too much to do.
4)Generics helps us to avoid such problems :
==> Developer don't need to do the BookKeeping of Downcast, whenever he is retrieving elements from some Global Structure like List, method(Object ) etc.
Casting problems are traced at Compile Time and not at RunTime, Thanks to Generics from Java5 and above.
==>Generics are mainly used to Use Collections easily, without Type Errors etc. Since Collections are used to store ant Type of Elements, and Generics are
there to provide Type Safety Stuff.
==>With Generics you can write Generic Code and User Of your Code provide Specific Type.
Ex:
<T> void printList(List<T> list){
for(T ele : list){
System.out.println(ele);
}
}
Now user Of printList, will use it like
List<Integer> ints = new ArrayList<Integer>();
ints.add(1);ints.add(2);ints.add(3);
Now user Of printList, will use it like
List<String> ints = new ArrayList<String>();
ints.add("abc");ints.add("xyz");ints.add("def");
So in both cases, we as don't need to handle different Types separately.
and our printList code is generic enough, not to get changed with different Types List from Consumer.
Ex:
method(Integer x){
//...
}
this method only accepts Integer param.
Now let say If we need to create Our Method Generic enough that users of method can pass types also.
Something like :
method(T x){
//...
}
Now here T depends on User type.
Let say :
User #1
Integer x = new Integer(5);
method(x);
User #2
String y = new String("abc");
method(y);
So our method is generic enough to consume any Input Argument Type.
We will discuss this appraoch more .
The Other approach is for method to have Object type input parameter.
method(Object x){
//...
}
Now this approach is good to certain extend.
Observations :
a)Since all non primitive types are subclass to Object, so client with non-primitive types can easily use method.
Integer x = new Integer(5);
method(x);
String y = new String("abc");
method(y);
Both these will work like a charm.
b)Problem arises when storing elements in collection of any Type just like List<Object>
Let say we have method :
methodList(){
List strList = new ArrayList();
strList.add("abc");
strList.add("def");
//Lets assume list has two elements.
Iterator iter = list.iterator();
while (iter.hasNext()) {
String str = (String)iter.next(); //We need to explicitly Downcast, Since List will return Object element.
System.out.println(str);
}
//Now we need to add one more element, which is Integer.
Integer ints = new Integer(5);
strList.add(ints);
//If we do
String str = (String) strList.get(2);
//This will throw ClassCastException : which means element is getting casted to incompatible Type and throw ClassCastException at RunTime.
}
So, Upcasting is Implicit, Because all non Primitive types are Subclasses Of Object.which can be done easily.
But in case of Downcasting, Programmer needs to take care of when to Downcast and Correct Type to Downcast.
3)We can use instance Of while doing downcast, but again its a too much to do that.
Maintaining each type and its associated if-else condition is too much to do.
4)Generics helps us to avoid such problems :
==> Developer don't need to do the BookKeeping of Downcast, whenever he is retrieving elements from some Global Structure like List, method(Object ) etc.
Casting problems are traced at Compile Time and not at RunTime, Thanks to Generics from Java5 and above.
==>Generics are mainly used to Use Collections easily, without Type Errors etc. Since Collections are used to store ant Type of Elements, and Generics are
there to provide Type Safety Stuff.
==>With Generics you can write Generic Code and User Of your Code provide Specific Type.
Ex:
<T> void printList(List<T> list){
for(T ele : list){
System.out.println(ele);
}
}
Now user Of printList, will use it like
List<Integer> ints = new ArrayList<Integer>();
ints.add(1);ints.add(2);ints.add(3);
Now user Of printList, will use it like
List<String> ints = new ArrayList<String>();
ints.add("abc");ints.add("xyz");ints.add("def");
So in both cases, we as don't need to handle different Types separately.
and our printList code is generic enough, not to get changed with different Types List from Consumer.