views:

621

answers:

3

I saw a java function that looked something like this-

public static<T> foo() {...}

I know what generics are but can someone explain the in this context? Who decides what T is equal to? Whats going on here?

EDIT: Can someone please show me an example of a function like this.

+9  A: 

You've missed the return type out, but apart from that it's a generic method. As with generic types, T stands in for any reference type (within bounds if given).

For methods, generic parameters are typically inferred by the compiler. In certain situations you might want to specify the generic arguments yourself, using a slightly peculiar syntax:

    List<String> strings = Collections.<String>emptyList();

In this case, the compiler could have inferred the type, but it's not always obvious whether the compiler can or can't. Note, the <> is after the dot. For syntactical reasons the type name or target object must always be specified.

It's possible to have generic constructors, but I've never seen one in the wild and the syntax gets worse.

I believe C++ and C# syntaxes place the generic types after the method/function name.

Tom Hawtin - tackline
Agh! My eyes! It burns!
skaffman
you rock. Behold, true java guru! /bows down/ :D
Here Be Wolves
Please see my edit.
quilby
A: 

T it's the formal type parameter wich will be replaced by the actual type argument used at the instantiation of the object.

For example, here is the List and Iterator definitios in package java.util:

public interface List<E>{
  void add(E x);
  Iterator<E> iterator();
}

public interface Iterator<E>{
  E next();
  boolean hasNext();
}

Then you can instantiate a List this way:

List<String> ls = new ArrayList<String>()

Where you might imagine that List stands for a version of List where E has been uniformly replaced by String:

public interface StringList{
  void add(String x)
  Iterator<String> iterator();
}
Eliseo Ocampos
There's not necessarily any object being instantiated. (Using a reasonable guess at what the example should have been.)
Tom Hawtin - tackline
Hhmm.. you're right, the replacemente its done at _compilation_ time (but anyway, this will be used to instantiate the object later)
Eliseo Ocampos
There needn't be any object instantiation going on at all. The syntax appears to be for generic methods, not generic types. (Technically the questioner's example needs one replacement to get to a valid syntax which could be `public <T> foo() { ... }` which is technically valid syntax for a class named `foo` (or does the compiler complain about not using the generic parameter?).)
Tom Hawtin - tackline
Well, you're right again, I should pay more attention :P. And no, the compiler won't complain about it.
Eliseo Ocampos
This is not relevant to my question.
quilby
+2  A: 

The context is a generic method as opposed to a class. The variable <T> applies only to the call of the method.. The Collections class has a number of these; the class itself is not generic, but many of the methods are.

The compiler decides what T is equal to -- it equals whatever gets the types to work. Sometimes this is easier then others.

For example, the method static <T> Set<T> Collections.singleton(T o) the type is defined in the parameter:

Collections.singleton(String T)

will return a Set<String>.

Sometimes the type is hard to define. For example sometimes there is not easily enough information to type Collection.emptyList(). In that case you can specify the type directly: Collection.<String>emptyList().

Kathy Van Stone
Please see my edit
quilby