Reputation: 61081
Browsing through Guava libraries I saw this weird signature on the readLines
method of the Files
class:
public static <T> T readLines(File file,
Charset charset,
LineProcessor<T> callback)
I know a little bit about generics in Java, but this baffled me.
What does the double T
mean here? And why is the first one in angled brackets?
After some answers, I am still not clear as to why I should use a T
inside the brackets. Why for example can't it just be:
public static <> T readLines()
or
public static <K> T readLines()
Or does the Java syntax dictate that the same letter must be used?
Now this is even wierder:
static <T> void fromArrayToCollection(T[] a, Collection<T> c) {
how can a method have a generic-return type and be void
?
Upvotes: 6
Views: 1031
Reputation: 15656
Instead of being generic at class level only the method readLines uses generics.
<T>
declares the generic types used by the methodT
is the return type.The first one uses the same syntax as a generic class to declare the generic types. Instead you could write
class Generic <T>
{
public static T readLines(File file,
Charset charset,
LineProcessor<T> callback)
}
This however would make all instances of the class generic.
Extended Example:
public static <ElementType,ListType extends List<ElementType>> ListType add(ListType list,ElementType elem)
{
list.add(elem);
return list;
}
ArrayList<String> al = add(add(new ArrayList<String>(),"Hello"),"World");
The method adds a given Element to a List and returns the List.
The method uses two generic Types one for the elements of the list and one for the list itself.
The names used are nothing special, using a T
for a generic type is like using i
for an integer.
ElementType
is the name used for the generic Type of the elements (any valid variable name / identifier could be used)ListType
is the name for the generic list Type, the classes used have to extend/implement List
for the ElementType
.The example calls the method with:
ElementType
= String
ListType
= ArrayList<String>
which would result in
public static ArrayList<String> add(ArrayList<String> list, String elem)
Bloat end :-)
Upvotes: 4
Reputation: 11017
The first T
inside the angle brackets mean that the method itself is generic. The second T
is the return type. T
can be any type within its bounds. In this case, T
has no bounds.
T will be determined at the call site, and in this case, inferred from the LineProcessor<T>
parameter.
Upvotes: 7
Reputation: 206816
I am still not clear as to why I should use a T inside the brackets. Why for example can't it just be:
public static <> T readLines()
or
public static <K> T readLines()
Or does the java syntax dictate that the SAME letter must be used?
The <T>
or <K>
is the type parameter. If you write <K> T
, then the T isn't a type parameter - rather, you're using the specific class T
. This won't work if you don't have a class that's literally named T
in scope.
Now this is even wierder:
static <T> void fromArrayToCollection(T[] a, Collection<T> c) {
how can a method have a generic-return type and be void?
It doesn't; the <T>
is not a "generic return type", it's just the type parameter to the method. You're saying that the method is generic, and T
is the type parameter. The return type of the method is void
.
Upvotes: 4
Reputation: 8734
It's a generic method -- the T
is called a type parameter, and can represent any type. So if I have a method with this signature:
public <T> T foo(T[] bar)
I can call it on any array, and it will return a single object of the same type. If I pass it a String array, I'll get back a String, and so on. More information in the Sun tutorials for "generic methods".
Edit: In answer to your updated question, bear in mind that the first <T>
isn't part of the return type: it's just an indicator that T
is a type parameter. So look at the example you quoted:
static <T> void fromArrayToCollection(T[] a, Collection<T> c)
That just means that fromArrayToCollection
will accept any array and any collection, but that they must be an array and collection of the same type. So you can pass in a String[]
and a Collection<String>
, or an Integer[]
and a Collection<Integer>
, but not a String[]
and a Collection<Integer>
. No matter what type you put in for T
, the method returns nothing.
Upvotes: 10
Reputation: 56772
This is a generic method.
Actually there are three Ts, the third on LineProcessor<T>
specifies T when you use the method.
Upvotes: 0