Sunday, April 22, 2012

Shortest Ever Java Generics Tutorial


Location of Declaration

Formal type parameters can be applied at either the class or method level:

public class SomeClass<A> {

    // <A> Declared at the class level
    A methodA(A a) {
        return a;
    }

    // <B> Declared at the method level.
    <B> B methodB(B b) {
        return b;
    }
}

Class level type parameters can only by used in non-static context.


Wildcard Declarations

Wildcard parameters allow you more flexibility in your assignments,
but they don't allow you to violate type safety.
So the following declaration is illegal:

ArrayList<Number> numbers = new ArrayList<BigDecimal>();

Because you could violate type safety by adding a BigInteger to the numbers collection.
However the following is okay:

ArrayList<? extends Number> numbers = new ArrayList<BigDecimal>();

Because you can't use the numbers variable to add new elements to the array.

A quick way to think of the wildcard forms is:


DeclarationDescription EffectUsable methods
List<Number>List of NumbersRead/Writelist.get(0);
list.add(number);
list.size();
List<? extends Number>List of Number or List of BigDecimalRead onlylist.get(0);
list.size();
List<? super Number>List of Number or List of ObjectWrite onlylist.add(number);
list.size();
List<?>List of unknown...list.size();


The last form may not seem that useful, however you can still perform many "Collection" operations such as getting the size or reversing the elements in the list.

Exceptions

Since all objects inherit from java.lang.Object it is possible to read an Object from any of the lists.
However the last two cases will be of type java.lang.Object
(The only way to maintain type safety is to down cast to Object).


Since removal of elements doesn't create any type safety issues, it is possible to remove elements from all 4 examples.
So the second and forth examples only really prevent addition of new elements.

Another way to put it is that remove() is a collection level operation, like size.

Disclaimer

  1. In the interests of brevity I have bent the truth (a bit) with respect to wildcard declarations.
  2. There might be a shorter tutorial that I am not aware of.