Generics uses something called 'formal type parameters', which are virtual type placeholders for actual types. For ex., in your example T is an virtual type and String is the actual type.
A class can make use of any number of format type parameters, and should be defined while declaring the class.
For ex.,
makes use of one formal parameter and
makes use of two formal type parameters.
Given formal type parameter always points to one actual type. So using the same formal type at any place, requires same actual type to be specified.
If I define
Test<Object, String> newTest = new Test<Object, String>();, means wherever the type A is referred in the Test class, I can expect Object type and wherever B is referred, I can expect String type.
Please note that both virtual types can be mapped to same actual type as in, Test<String, String> newTest = new Test<String, String>();
Back to your example.
In this case, writeAll method expect two arguments of SAME actual type and returns the same actual type.
So it is violation of this contract if you execute below code, as it passes two different actual types (Object and String).
Hope I didn't make you more confused
[ July 08, 2008: Message edited by: Santhosh Kumar ]
[ July 08, 2008: Message edited by: Santhosh Kumar ]