More on generics
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>