Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 3 of 3
Vector<?>
Note: That code differs from Vector<Object> for the same reasons discussed above.
So far we've used the built-in parameterized types in Java. Now let's look at the other side of the coin—creating parameterized
types. It's fairly easy to create your own parameterized types. As an example, let's create a new class called Mammals that can store any Mammal:
class Mammals<T extends Mammal>
{
private Vector<T> items = new Vector<T>();
void add(T item)
{
items.add(item);
}
T get(int index)
{
return items.get(index);
}
}
Now you can use this new class in your code, as shown in the following fragment:
// A list of dogs Mammals<Dog> dogs2 = new Mammals<Dog>(); dogs2.add(new Dog()); dogs2.add(new Dog()); // A list of cats Mammals<Cat> cats2 = new Mammals<Cat>(); cats2.add(new Cat()); cats2.add(new Cat()); cats2.add(new Cat()); // Assign the dogs to a generic list of mammals Mammals<? extends Mammal> mammals = dogs2;
To support iterating through the Mammals list, I modify the class as follows:
class Mammals<E extends Mammal> extends Vector<E>
{
}
No, I did not forget the code in the class. I extended the Vector class and inherited all the required functionality (Isn't that what object-oriented programming is all about?). Now we can
iterate through the list, as shown below:
Mammals<? extends Mammal> mammals = dogs2;
for (Mammal m: mammals)
{
m.eat();
}
mammals = cats2;
for (Mammal m: mammals)
{
m.eat();
}
J2SE 1.5 supports generic methods. To see how such methods can be useful, let's say you wanted to create a method that took
an array of Mammals and put them in a Mammals list. Here's one way of accomplishing that:
// Mammals class from earlier example
class Mammals<E extends Mammal> extends Vector<E>
{
}
// A generic method
static <T extends Mammal> void arrayToList(T[] array, Mammals<T> list)
{
for(T item: array)
list.add(item);
}
Generic methods prove especially useful when new functionality to an existing parameterized class is needed and it is not possible to extend the class, or when a group of such methods are provided as common utility methods.
I talked at length about generics in this article. Generics are a strong addition to Java and provide a level compile-time type safety not possible in previous versions of the language. They are also used extensively within J2SE 1.5. In addition, not surprisingly, Reflection in J2SE 1.5 has also been extended to support reflecting on generic types. However, those details reach beyond the scope of this introductory article. Perhaps, if there is enough interest, I will write an article exclusively on using Reflection on generics (and a potential weakness with Java's generics implementation called erasure).
In the third and final part of this series, I will go into details about the newly introduced metadata feature in J2SE 1.5 called annotations. Annotations allow programmers to decorate Java code with their own attributes that can be used for code documentation, code generation, and, during runtime, for providing special services such as enhanced business-level security or special business logic.
Archived Discussions (Read only)