Monday, June 13, 2011

Java Generics

Now for something completely different...

Java 5 introduced the notion of generics, which aim was to remove some of the problems surrounding casting from a unspecified object to a concrete one. This problem is especially noticeable when working with collections of unspecified objects. Let's try with a small example to illustrate the problem:

//In some class maybe a cheese factory 
public void doSomethingWithCheese(Collection cheeses){
   Iterator cheeseIterator = cheeses.iterator();
 
   while(cheeseIterator.hasNext()){
      Cheese currentCheese = (Cheese)cheeseIterator.next();
      currentCheese.cheeseBehavior();
   }
}

class Cheese {
   public void cheeseBehavior(){}
}

class Animal {}

//Some code
Collection cheeses = new LinkedList();
cheeses.add(new Cheese());
cheeses.add(new Animal());

//This call causes a classCastException because we have added an animal to the list of cheeses, and just so you know it, animals and cheeses doesn't mix well  
cheeseFactory.doSomethingWithCheese(cheeses);
The main problem with this code is that we have introduced an error which can only be detected at runtime, the compiler dosen't check your code to see if you are an idiot and mixes animals with cheeses.

Now let's rewrite the solution using generics.

public void doSomethingWithCheese(Collection cheeses){
   for(Cheese currentCheese : cheeses){
      currentCheese.cheeseBehavior();
   }
}

//Some code
Collection cheeses = new LinkedList();
cheeses.add(new Cheese());
cheeses.add(new Animal());


Now that we are using generics the the adding of an animal to the list of cheeses, is no longer possible and will result in a compile-time error.

Furthermore, when using generics it's possible to use the new foreach loop, instead of iterating through the Collection using a iterator.

Special concerns using generics:

Inheritance

use <? extends parrent >

You might think that Collection<Object> could contain any class that inherits from Object (in java all objects inherits from Object), this is not so. If you want a Collection that can contain any given object, you should use <?&gt.

When using <?> or <? extends>, it's only possible to add objects as long as you are in the same scope as to where the collection was first initialized.

No comments: