Paramaterized Java Classes

One of the biggest features of Java 1.5 was generics. In particular all the collection classes had been extended to use parametrized classes. Normally the collection classes accepted and returned Objects which is the class all other Java classes descend from. Unfortunately this meant that you had to cast everything you got back out of a collection to what you expected it to be. and until you did you would only be able to call methods that were provided by Object. You also had to be ready to catch an exception in case the class could not be cast because it was the wrong object.

Generics and parametrized classes allow Java programmers to place a type on a class and have that type inherited by its methods. For example you can now declare an ArrayList class with a type String. This alters the ArrayList class so that its add method now only accepts objects of type String, the get method now also returns objects of type String. This makes everything type safe which means you don’t have to cast anything and your code won’t compile if you try to put something in the ArrayList that doesn’t match its class.

Java uses parametrized classes to build its collections and you’ll want to use them too if you’re making your own collection class. For example if you were implementing a stack, a queue or a multi-priority FIFO queue are good cases for parametrized classes. Be careful though of the lure parametrized classes can have. They are not a replacement for polymorphism and shouldn’t be used when polymorphism would make more sense. For example if your multi-priority queue gets the priority out of the object itself then you’d need an interface that provides a method to get the priority. Then your class will only be able to accept items that implement that interface, which makes sense in this case as we need to priority to be able to store it.

A parametrized class is really simple to use. Here is an example implementation of a stack collection backed by an ArrayList:

import java.util.ArrayList;
import java.util.Collection;

/**
 * This class acts as a stack. Items can be 'pushed' which adds them to the top
 * of the stack. items can also be 'popped' which removes and returns the top
 * item on the stack and removes it. This means only the most recently added
 * item is available at the current time. To get to older items you need to
 * first remove the others.
 * 
 * Note: Java already has a stack object that should probably be used in
 *       preference to this one. This is only an example implementation.
 * 
 * @author Daniel Hall <daniel@danielhall.me>
 *
 * @param <T> The type of items that can be stored in the Stack.
 */
public class Stack<T> {
	/* Uses the same type as this class to store the items */
	private ArrayList<T> array = new ArrayList<T>();
	
	/**
	 * Creates a Stack containing items already in a collection. The collection
	 * must have the same parameterized type as this class to ensure that we get
	 * the right objects.
	 * @param c The Collection to initialize with
	 */
	public Stack(Collection<T> c) {
		array.addAll(c);
	}
	
	/**
	 * Creates an empty Stack object
	 */
	public Stack() {
		
	}
	
	/**
	 * Adds an item to the top of the stack.
	 * @param item The item which will be added to the top of the stack.
	 */
	public void push(T item) {
		array.add(item);
	}
	
	/**
	 * Removes the first item from the stack
	 * @return The item that was on the top of the stack.
	 */
	public T pop() {
		/* This gets the size so we don't have to do it twice. */
		int count = array.size();
		
		/* If the stack is empty return null, note that the Java implementation
		 * of stack throws an Exception instead.
		 */
		if (count == 0) {
			return null;
		}
		
		/* Remove the last added object (which will have index count - 1) */
		return array.remove(count - 1);
	}
}

Random thought: John Lions wrote a book about the Unix source code, in the seventies, which because it also included some code, was blocked from being published until 1996.