For arraycopy, it is sufficient for the type of the target array tgt to be a supertype of the source array src. We can specify that the two arrays are of different types by using multiple type variables, say S and T. As a first step, we write
public <S,T> void arraycopy (S[] src, T[] tgt){ ... }
This, however, does not define any constraints on the types assigned to S and T. We want S to be a subtype of T, so we can make our definition more precise by writing2:
public <S extends T,T> void arraycopy (S[] src, T[] tgt){ ... }
As another example, suppose we want to relax our typing constraint for lists to allow a list of type T to store elements of any subtype of T. We could then define insert as follows:
public class LinkedList<T>{ ... public <S extends T> void insert(S newdata){ ... // code to insert newdata in list } }
Now we cannot be sure, in general, about the specific type of each element of the list. However, we do still know that all values in the list are compatible with type T. Thus, the definition and type of the function head remain the same as before:
public T head(){ T returnval; ... return returnval; }
Madhavan Mukund 2006-02-19