I'm reading "Generics in the Java Programming Language" by Gilad Bracha and I'm confused about a style of declaration. The following code is found on page 8:
interface Collection<E>
{
public boolean containsAll(Collection<?> c);
public boolean addAll(Collection<? extends E> c);
}
interface Collection<E>
{
public <T> boolean containsAll(Collection<T> c);
public <T extends E> boolean addAll(Collection<T> c);
// hey, type variables can have bounds too!
}
My point of confusion comes from the second declaration. It's not clear to me what the purpose the <T>
declaration serves in the following line:
public <T> boolean containsAll(Collection<T> c);
The method already has a type (boolean) associated with it.
Why would you use the <T>
and what does it tell the complier?
I think my question needs to be a bit more specific.
Why would you write:
public <T> boolean containsAll(Collection<T> c);
vs
public boolean containsAll(Collection<T> c);
It's not clear to me, what the purpose of <T>
is, in the first declaration of containsAll.
For static generic methods, the type parameter section must appear before the method's return type. The complete syntax for invoking this method would be: Pair<Integer, String> p1 = new Pair<>(1, "apple"); Pair<Integer, String> p2 = new Pair<>(2, "pear"); boolean same = Util. <Integer, String>compare(p1, p2);
Generics means parameterized types. The idea is to allow type (Integer, String, … etc., and user-defined types) to be a parameter to methods, classes, and interfaces. Using Generics, it is possible to create classes that work with different data types.
The declaration of a generic class is almost the same as that of a non-generic class except the class name is followed by a type parameter section. The type parameter section of a generic class can have one or more type parameters separated by commas.
Generic MethodsAll generic method declarations have a type parameter section delimited by angle brackets (< and >) that precedes the method's return type ( < E > in the next example). Each type parameter section contains one or more type parameters separated by commas.
As far as I can tell, in this case <T>
doesn't provide anything useful at all. It creates a method that is completely functionally equivalent to those using the wildcard instead.
Here are a couple of examples where it would be useful:
public List<?> transform(List<?> in);
//vs
public <T> List<T> transform(List<T> in);
In the above, you can correlate the return type with the input type. The first example cannot correlate the runtime type of the two wildcards.
public void add(List<?> list, Object obj);
//vs
public <T> void add(List<? super T> list, T obj);
In the above, the first method won't even be able to add obj
to list
since it can't be deemed to be type safe. The generic parameter in the second ensures that list
can hold whatever type obj
is.
The method already has a type (boolean) associated with it.
That is the return type. The full type of the method is “method that takes a Collection<T>
(for some T
) parameter and returns a boolean
”.
And this is where T
comes in: the parameter of the function uses it. In other words, this method can be called with different types as argument. The only restriction of these types is that they must implement the Collection<T>
interface, which itself relies on a generic argument T
(the type of the objects stored in the collection).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With