Generic Types – III


Generic Declarations

For example, this is the API declaration for the java.util.List interface:
public interface List<E>
The <E> is a placeholder for the type you pass in. The List interface is behaving as a generic “template” (sort of like C++ templates), and when you write your code, you change it from a generic List to a List<Dog> or List<Integer>, and so on.The E, by the way, is only a convention. Any valid Java identifier would work here, but E stands for “Element,” and it’s used when the template is a collection. The other main convention is T (stands for “type”), used for, well, things that are NOT collections.

Now that you’ve seen the interface declaration for List, what do you think the add() method looks like?
boolean add(E o)
In other words, whatever E is when you declare the List, that’s what you can add to it . So imagine this code:
                 List<Animal> list = new ArrayList<Animal>();

The E in the List API suddenly has its waveform collapsed, and goes from the abstract <your type goes here>, to a List of Animals. And if it’s a List of Animals, then the add() method of List must obviously behave like this:
                   boolean add(Animal a)

Making Your Own Generic Class

Here’s simple class that uses the parameterized type of the class in several ways:
                        public class TestGenerics<T> { // as the class type
                                          T anInstance; // as an instance variable type
                                          T [] anArrayOfTs; // as an array type
                              TestGenerics(T anInstance) { // as an argument type
                                          this.anInstance = anInstance;
                              }
                            T getT() { // as a return type
                               return anInstance;
                             }
                    }

You can use more than one parameterized type in a single class definition:
                    public class UseTwo<T, X> {
                           T one;
                           X two;
                           UseTwo(T one, X two) {
                                        this.one = one;
                                        this.two = two;
                           }
                           T getT() { return one; }
                           X getX() { return two; }

                     // test it by creating it with <String, Integer>
                           public static void main (String[] args) {
                                      UseTwo<String, Integer> twos = new UseTwo<String, Integer>(“foo”, 42);
                                      String theT = twos.getT(); // returns a String
                                      int theX = twos.getX(); // returns Integer, unboxes to int

                            }

                  }

Creating Generic Methods

Using a generic method, we can declare the method without a specific type and then get the type information based on the type of the object passed to the method. For example:
                          import java.util.*;
                          public class CreateAnArrayList {
                                     public <T> void makeArrayList(T t) { // take an object of an
                                                                                              // unknown type and use a
                                                                                              // “T” to represent the type
                                    List<T> list = new ArrayList<T>(); // now we can create the
                                                                                             // list using “T”
                                    list.add(t);
                                    }
                         }

In the preceding code, if you invoke the makeArrayList() method with a Dog instance, the method will behave as though it looked like this all along:
                           public void makeArrayList(Dog t) {
                                      List<Dog> list = new ArrayList<Dog>();
                                      list.add(t);
                           }

The strangest thing about generic methods is that you must declare the type variable BEFORE the return type of the method:
                       public <T> void makeArrayList(T t)
The <T> before void simply defines what T is before you use it as a type in the argument. You MUST declare the type like that unless the type is specified for the class.

You’re also free to put boundaries on the type you declare, for example, if you want to restrict the makeArrayList() method to only Number or its subtypes (Integer, Float, and so on) you would say
                         public <T extends Number> void makeArrayList(T t)

If you REALLY want to get ridiculous, you can declare a class with a name that is the same as the type parameter placeholder:
                           class X { public <X> X(X x) { } }
Yes, this works. The X that is the constructor name has no relationship to the <X> type declaration, which has no relationship to the constructor argument identifier, which is also, of course, X. The compiler is able to parse this and treat each of the different uses of X independently. So there is no naming conflict between class names, type parameter placeholders, and variable identifiers.

Advertisements

11 thoughts on “Generic Types – III

  1. Wonderful blog! I found it while surfing around on Yahoo News. Do you have any tips on how to get listed in Yahoo News? I’ve been trying for a while but I never seem to get there! Many thanks

    Like

  2. My partner and I stumbled over here different website and thought I should check things out. I like what I see so now i am following you. Look forward to looking into your web page repeatedly.

    Like

  3. Wonderful work! That is the type of information that are supposed to be shared across the web. Disgrace on Google for not positioning this publish upper! Come on over and seek advice from my web site . Thanks =)

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s