Generics is a java feature introduced as part of Java 1.5. It ensures
Type safety(provides type checking during java compile time)
Code reusability
Removes the possibility of classCastException during runtime.
Any generic java type(Class, interface etc) and methods are basically datatypes and functions which are strictly parameterized over a data type respectively. Since Java 5 whole collection classes are rewritten using generics to ensure type safety.
Pre Java 5 code
List myList = new ArrayList(); // cant declare a type
myList.add(new Dog()); // and it will hold Dogs too
mylist.add(new Integer(42)); // and Integers….
myList.add(“Fred”); // OK it will hold String
Here getting a String back from String-intended list requires a cast.
String s = (String) myList.get(0);
With Generics
<code>
List<String> myList = new ArrayList<String>();
myList.add(“Fred”); //OK, it will hold Strings
myList.add(new Dog()); // compiler error!!
</code>
But String s=myList.get(0);
Now myList ensures always a string to be returned.
Simillarly,
<code>
void takeListOfStrings(List<String> strings){
strings. add (“ foo”); // no problem adding a String
}
void takeListOfString( List<String> strings) {
strings.add(new Integer(42)); // NO!! Strings is type safe
}
</code>
Return types can be declared type safe
<code>
public Set<Dog> getDogList(){
Set<Dog> dogs = new HashSet<Dog>();
return dogs;
}
Dog d = getDogList().get(0);
</code>
But Pre Java 5
<code>
Public Set getDogList(){
Set dogs = new HashSet();
return dogs;
}
Dog d =(Dog) getDogList().get(0);
</code>
Generics and legacy code
The biggest challenge for Sun in adding generics to the language was how to deal with legacy code built without generics.
List myList = new ArrayList(); Becomes
List<Integer> myList = new ArrayList<Integer>();
public List changeStrings(ArrayList s){} to
public List<String> changeStrings (ArrayList<String> s){}
Integer i = list.get(0);
Mixing Generic and Non-generic collections
We have a ArrayList, of type Integer and we are passing it into a method from a class
whose source code we don’t have access to.
Will this work?
<code>
Import java.util.*;
Public class TestLegacy{
Public static void main(String args[]){
List<Integer> myList = new ArrayList<Integer>();
myList.add(4);
myList.add(6);
Adder adder = new Adder();
int total = adder.addAll(myList);
System.out.println(total);
}
}</code>
<code>
import java.util.*;
class Adder {
int addAll(List list) {
Iterator it = list.iterator();
int total = 0;
while(it.hasNext()){
int i = ((Integer) (t. next()). intValue();
total += i;
}
return total;
}
}
</code>
<code>
import java.util.*;
public class TestBadLegacy{
public static void main(String args[]){
List<Integer> myList = new ArrayList<Integer>();
myList.add(4);
myList.add(6);
Inserter in = new Inserter();
in,insert(myList);
}
}
Class Inserter{
Void insert(List list){
List.add(new Integer(42));
}
}
</code>
Here void insert(List list) {
list.add(new String(“42”));
}
The compiler will warn that you are taking a big risk sending protected
ArrayList<Integer> into a dangerous method that can have its way with your list and put in Floats, Strings, or even Dogs.
Polymorphism and Generics
The type of the variable declaration must match the type you pass to the actual object type. If you declare List<Foo> foo then whatever you assign to the foo reference MUST be of the generic type <Foo>. Not a subtype of <Foo>. Not a super type of <Foo>.Just <Foo>..
<code>
List<Integer> myList = new ArrayList<Integer> ();
Class Parent{}
Class Child extends Parent {}
List<Parent> myList = new ArrayList<Child>();
List<Object> myList = new ArrayList< JButton>();//NO!
List<Number> numbers = new ArrayList <Integer>(); //NO!
</code>
But these are fine
<code>
List<JButton> myList = new ArrayList< JButton>(); //yes
List<Object> myList = new ArrayList<Object>(); // yes
List<Integer> myList = new ArrayList<Integer>(); // yes
</code>
Wild Cards
public void addAnimal (List <Animal> animals)
to
public void addAnimal(List<? extends Animal> animals)
<code>
public void addAnimal(List<? extends Animal> animals) {
animals.add(new Dog());//NO! cant add if we
//use <? Extends Animal>
}
</code>
void foo(List<? extends Serializable> list) // odd, but correct to use extends
<code>
public void addAnimal(List<? Super Dog> animals){
animals.add(new Dog()); // adding is sometimes OK with super
}
public static void main(String[] args){
List<Animal> animals = new ArrayList<Animal>();
animals.add(new Dog());
animals.add(new Dog());
AnimalDoctorGeneric doc = new AnimalDoctorGeneric();
doc.addAnimal(animals); // passing an Animal List
}
</code>
Tricky interview Questions
<code>
public static void main(String[] args){
Queue<String> q = new LinkedList<String>();
q. add(“ veronica”);
q. add(“ Wallace”);
q. add(“ Duncan”);
showAll ( q);
}
public static void showAll(Queue q){
q.add(new Integer(42));
while (!q. isEmpty())
System.out.print(q.remove() + “”);
}
</code>
What is the result?
Veronica Wallace Duncan
Veronica Wallace Duncan 42
Duncan Wallace Veronica
42 Duncan Wallace Veronica
Compilation fails
An exception occurs at runtime.
Still not comfortable check more interview questions here.