Reading code can be very enlightening but I have been following this practice only recently.One might come across nuggets that explain a particular code pattern clearly when one reads code.
Twitter has open-sourced its ‘Commons’ library and I came across the Curiously Recurring Generic Pattern and the Self-bounding pattern in it. These two are discussed in ‘Thinking in Java’ by Bruce Eckel. He also gives an exercise at the end of Page 709.
Exercise 34: Create a self-bounded generic type that contains an
abstract method that takes an argument of the generic type parameter and
produces a return value of the generic type parameter. In a non-abstract
method of the class, call the abstract method and return its result. Inherit
from the self-bounded type and test the resulting class
The code for this exercise could be
public abstract class SelfBound< T extends SelfBound<T>>{
public abstract T get( T t );
public T getValue( T t){
return get( t );
}
public class SubSelfBound extends SelfBound{
public SubSelfBound get(SubSelfBound subSelfBound) {
return this;
}
public static void main( String[] argv ){
SubSelfBound subSelfBound = new SubSelfBound();
subSelfBound.test();
}
private void test() {
SubSelfBound subSelfBound = new SubSelfBound();
subSelfBound = getValue( subSelfBound );//The sub-class's inherited method is forced
//to take only the derived type as parameter
//and not the base type. The parameter varies
//and matches the derived type( Covariant )
SelfBound selfBound = getValue( subSelfBound );//It also returns the super type.
//This is related to the covariant
//return types according to the book.
}
}
Even though I might not have the absolutely correct solution here the idea is clear and it is that the Curiously Recurring Generic Pattern and the Self-bounding pattern are similar and the Self-bounding pattern permits a type of covariant argument types.
I used to think only covariant return types are possible in J2SE 5 but there seems to be a way to implement covariant argument types also though the practical applications of this concept could stupify the developers because not many are
used to advanced generics.
I understood all of this by reading the Twitter Commons source code that has used self-bounding types like this.
public interface Unit<U extends Unit<U>>;{
double multiplier();
}
If one is not used to thinking about Java generics deeply this type of code will be
hard to understand and implement.