tags:

views:

257

answers:

3

"When you declare a type parameter for the class, you can simply use that type any place that you'd use a real class or interface type. The type declared in the method argument is essentially replaced with the type you use when you instantiate the class.

If the class itself doesn't use a type parameter, you can still specify one for a method, by declaring it in a really unusual (but available) space-before the return type, This method says that T can be "any type of Animal"."

Can you explain?

+7  A: 

What it means is that in a generic class, you can write methods like so:

public T doSomething () {
}

Note that the return type is 'T'.

At compile-time, the return type of that method will be whatever you have passed to the generic class when you instantiated it.

Noon Silk
+1 - Nice, succinct.
duffymo
+1  A: 
class Zoo<T> {
   static void putAnimal(T animal) {
       // do stuff
   }
}

Zoo<Ape> apeZoo = new Zoo<Ape>(); // you can now put apes (and chimps) here
Zoo<Reptile> monkeyZoo = new Zoo<Reptile>(); // this zoo takes reptiles

apeZoo.putAnimal(new Chimp());
monkeyZoo.putAnimal(new Tortoise());
Otto Allmendinger
+1  A: 

For the first paragraph, this is just how generics work for classes. For instance, for list, you can create a list of a generic type, such as integer, e.g.:

ArrayList<Integer> list = new ArrayList<Integer>();

(in real code you'd use List<Integer> of course)

Now ArrayList will be defined as:

public class Arraylist<T> { // implements....

    // ...

    public T get(int index) {
         // ...
    }
}

Which is what makes it possible to use the get method on list and get an Integer (because we made a class of type ArrayList<Integer> so T = Integer). Otherwise the compiler would have no idea what types of objects the list was storing and you'd have to get the method to return an Object, which is how it used to be.

What the second paragraph means is that you can add type parameters to methods just as you can to classes. e.g.:

public <T> void noOp(T element) {
    // code here
}

This would allow you, for instance, to create a static utility method that returns something of type T. To return the first element of a List of T's:

public static <T> T getFirst (List<T> list) {
    return list.get(0);
}

And you could use this method in a strongly typed fashion. Suggestions for better examples welcome. :-)

edit: I just realised I once wrote something that uses this functionality. I was using the JPA API and getting really annoyed at all the times you have to return something (a list, or a single item) from a query, and running into unchecked type warnings because there's no way to infer the type here. If you're like me and trying to avoid warnings in your code, you'd have to suppress the warnings every single time. So I wrote this method to suppress the warnings for me:

@SuppressWarnings("unchecked")
public static <T> List<T> returnResultList(Query query) {
    return (List<T>)query.getResultList();
}

Which through the magic of type inference works on:

List<Integer> list = returnResultList(query);
wds
+1 for picking up on the OP's second paragraph. Those are decent examples; java.util.Collections has others.
kdgregory
Thanks. Decent as in they illustrate how it works quite well I think, but they're not exactly real world. :-)
wds