I have read it, although I am not quite understand about it previously. Can I interpret that generic method is used to express dependencies among the type of one or more arguments to a method and/or return type.
in the above example, there is not much difference, but I prefer second one.
Generic methods allow type parameters to be used to express dependencies among the types of one or more arguments to a method and/or its return type. If there isn't such a dependency, a generic method should not be used
consider the below code:
it is more expressive that src may contains subclass of T and you are going to copy the element from src to dest which is a T. here <T> expression depends on <? extends T> . so in this situation you should use generic method instead of wilcard. else I prefere wildcard.
It depends. If you don't need T inside the method, then the second form is just fine. It allows you to read the contents without being able to modify the collection. And since T is not needed inside the method, the type obviously does not matter, so using Object for the reference type of the individual elements will be OK.
Jesper de Jong wrote:
Why do you prefer the second one?
even if you use T inside the method, I suppose you can not do useful operations on T . still we can mange with object reference in the case of 2nd.Please, correct me if I am wrong
You're not completely right. No, you cannot use T to create instances or arrays. But you can use it as the generic type for other objects. By using a method generic type T you can create an ArrayList<T> inside the method. By using just <?> you cannot. And that's what I meant by needing T inside the method.
Generics are a compile time mechanism.
Wildcards are a runtime mechanism.
consider the following two alternatives
<T> void bar(Blah<T extends BaseType> tb);
void bar(Blah<? extends BaseType> tb);
When you instantiate generics version of bar() with two different types
two implementations of bar() are supposed to be generated by the compiler (see note A below)
void bar(Blah<DerType> )
void bar(Blah<DerSecondType> )
Both exist using the mechanism called ‘function overloading’.
However when you use the wildcard version with two different types,
it uses the single implementation for the two calls.
No ‘function overloading’ here.
This is because Blah<? extends BaseType> is supposed to be the base type of both
Blah<DerType> and Blah<DerSecondType>
just as BaseType is the base type of both
DerType and DerSecondType.
Two implementations generated by the compiler is conceptual.
Two implementations are not actually generated by the compiler.
It is optimised into one implementation by the mechanism called 'type erasure'.