Java Generics (2008)

Notes on SCJP I did in 2008

Generics

 

Straight forward Type Safe Collections

 

List<Animal> myList = new ArrayList<Animal>();

 

the generic type in the declaration must match on both side of = , in this case <String>

(unless a wildcard is used to the left of the equals OR the ref has no gen type eg List myList).

 

can only add <Animal> or subtypes to myList

eg

 

myList.add(new Animal()); // GOOD

myList.add(new Dog()); // GOOD

 

myList.add(new Integer()); //ERROR

 

Passing / Returning from method

void myMeth(List<Animal> animals){ …

 

can accept

List<Animal>, Vector<Animal> // GOOD

 

cannot accept

List<Dog>, ArrayLis<Cat> // ERROR

 

 

Mixing Old and New Collections

List<Integer> list = new ArrayList<Integer>();

 

oldClass.alterList(list)

class OldClass{

    void alterList(List List){

       list.add(” a string ! “); // works

   }

 

Its not until someone calls a Integer method on the String obj in the collection that it will blow up ! 

However the compiler will issue a warning.

 

 

Type Safe Collections with wildcards

When you dont need to add to a collection

void lookAtThis(List<? extends Animal>){ …

 

can take:

 

List<Animal>

ArrayList<Dog>

Vector<Lion>

etc

 

can also take class type that implements an interface. [eg Animal implements ManEater]

 

List<? extends Animal> li = new ArrayList<Dog>(); // GOOD

this means assign anything to li that is Animal or subclass BUT will not be able to add to it

 

List<?> list is equivalent to : List<? extends Object>

 

Wildcards when you need to add to a collection 

void addTo(List<? super Dog> list){ …

 

this can take:

 

List<Dog>

List<Animal>

List<Object>

 

adding to:

 

list.add(new Dog()); // GOOD

 

list.add(new Object()); // ERROR

list.add(new Animal()); // ERROR

 

 

List<? super Dog> li = new ArrayList<Animal>(); // GOOD, looks abit weird usually more specific on right eg List l = new ArrayList();

li.add(new Animal()); // ERROR weird but true

li.add(new Alsatian()); // GOOD

 

Summary:

When see a ref that has notation like List<?> this can take list of any type but cannot add to it.

See Pauls explanation as to why you can’t add to it (or any <? extends> ) 

 

Generic Type Reference Task is task valid? Notes
 
List<Animal> list list.add(new Dog()); Y OK add

NOT OK poly pass list type

pass this to it List <Dog> N
list.add(new Animal()); Y
 
List<? extends Animal> list list.add(anything); N OK pass poly generic subtypes

CAN NOT add to

pass ArrayList<Dog> Y
pass List<Alsatian> list Y
 
List<? super Dog> list list.add(new Dog()); Y OK pass generic supertype to it

OK ADD only the generic type to it

list.add(new Animal()); N
pass List<Dog> Y
pass List<Animal> Y

 

 

Templating your own Classes  

 A class can be templated (such as the collections classes have been in the API). Instance vars, method pass and return types can all be templated eg:

 

class GenExample<T>{

    T obj;

    List<T> myList;

 

    void meth1(T var){

       this.obj = var;

    }

 

    List<T> getList(){

       return myList;

    }

 

    T getObj(){

       return obj;

    }

}

 

if the class above was instantiated as  GenExample<String> eg = new GenExample<String>();

it would produce an instan ce of the class below. 

 

class GenExample<String>{

    String obj;

    List<String> myList;

 

    void meth1(String var){

       this.obj = var;

    }

 

    List<String> getList(){

       return myList;

    }

 

    String getObj(){

       return obj;

    }

}

 

Templating your own Methods 

 if you done need to template a whole class you could just template one method eg

 

public <T> void aMethod(T obj){ ….

 

here the template type MUST come before anything else including the return type.

 

For both class and methods you can put boundaries on them e.g.

 

public <T extends CharSequence> void aMethod(T obj){ ….

 

note the syntax is slightly different to that used when declaring a generice reference to something e.g. List<? extends Object> list

Leave a Comment