How to use Generic Java classes and why we need them
While the above writeup is informative, it leaves out two important things: how do we use these generic classes, and why do we even need them?
Let us begin by a (contrived) example. Let's say we want to have a Vector of Integer objects, we want to insert 1, 2, and 3 into the vector, and print out the second element. In normal Java, we would write the code like this:
Vector ints = new Vector;
//What if we insert something that is not an Integer?
Integer i = (Integer) ints.elementAt(2);
Now, there are some problems with this approach. One is that because the return type of elementAt() is Object, every time we extract an element from our vector, we need to remember what type of object the vector stores, and cast it accordingly. As any experienced Java programmer will tell you, most of the need for annoying downcasts comes from these kinds of operations.
The other problem is that addElement() expects something of type Object as parameter. This means that you can accidentally insert a string, as in the above code, and the compiler can't catch this mistake for you.
The solution is in generics aka parameterized types. That is, classes are allowed to have parameters that will determine their type. In our example, we can declare a Vector that will only accept objects of type Integer as the parameter to addElement(), and as the return type of elementAt(). Here's how our example would look in the GJ:
Vector ints = new Vector();
//now, if we add something that is not an integer,
//the compiler will detect the error
ints.addElement("Hello World!"); //<--- ERROR HERE
Integer i = ints.elementAt(2); //notice, no casts anymore!
As you can imagine, Generic components are very useful especially for container types like Vector, Stack, and Hashtable. It is widely expected that Sun will officially add generics into the jdk 1.5 version of Java.