Java Generics Basics

0

In this article, I will show you a Java Generics example and introduce you to few definitions that we will come across often.

But first..

What are Java Generics?

To answer this, I will use an example of Collections. After this example you will know why we call it ‘Java Generics’ and not ‘Java Types’ 🙂 after all its main purpose is to enforce type-safety.
Suppose we want a to create a List of Integers. In non-generic java, we do the following:

List list = new ArrayList();
list.add(new Integer(2));

Now, what happens if one adds a string to it. Does java compiler prevent it?

list.add("Hi!");

One can add a string to the list and it is perfectly legal.
But what about the below code?

Integer i = (Integer) list.get(1);

From compiler’s perspective, the code is still legal but at runtime we are sure to get ClassCastException. Remember, we had stored “Hi” in the second element of the list.
In the pre-generic era, we had no way to prevent this. Collections were heterogeneous. They can contain a mix of objects of different types.

With some extra coding one can enforce the restrictions on type to make the Collection a homogeneous object. Let’s us see how we can achieve this.

public class IntegerList implements List {
	private List internalList = new ArrayList();

	public boolean addInt(Integer i) {
		return internalList.add(i);
	}

	public Integer getInt(int i) {
		return (Integer) internalList.get(i);
	}
...
}

and test case…

	public void testIntList() {
		IntegerList l = new IntegerList();
		l.addInt(new Integer(4));
		assertEquals(4, l.getInt(0).intValue());
	}

The only issue with this kind of approach is that we will end up one implementation for each type. For example, for type string, StringList.

A more practical approach would be to have a single implementation of collection class and use it to hold elements of different types. In other words, we want to have one generic implementation of List that can be used for Integer, String or any other type.
This is what generics are for: implementation of one generic class that can be instantiated for a variety of types which is why it is called ‘Java Generics’

Now we will look into few definitions.

What is a formal type parameter

A formal type parameter defines a generic. For example, in the List interface below, <E> is the type parameter. It represents the type of element stored in the list.

public interface List<E> extends Collection<E> {
    Iterator<E> iterator();

    boolean add(E e);
    ...
}

A generic type can have one or more type parameters. An example would be the Map interface. There is one type parameter <K> for the key and another <V> for the value it is holding.

public interface Map<K,V> {
...
}

What is parameterized type?

The formal type parameter is a place holder that will later be replaced by a type argument when the generic type is instantiated and used. For example, the formal type parameter <E> is replaced by type argument Integer in the below instantiation of List:

List<Integer> l = new ArrayList<Integer>();

A parameterized type is an instantiation of generic type with actual type arguments.
If we want to create a List instance for type String, all we have to do is replace <E> with <String>

List<String> l = new ArrayList<String>();

A generic type declaration is compiled once and for all, and turned into a single class file, just like an ordinary class or interface declaration.
We will look into more examples of generics in my coming articles.

About Author

Ram’s expertise lies in test driven development and re-factoring. He is passionate about open source technologies and loves blogging on various java and open-source technologies like spring.
You can reach him at [email protected]

Leave A Reply