Java Generics

What is Generics in Java


Generic in Java is another beautiful feature introduced in JDK 1.5 along with Enum and variable arguments which allows java programmer to write more robust and type-safe code. In my opinion generics in Java is much overdue feature given popularity of Collection framework in java and its limitation around handling type-safety. Though generics may look very complex if you are not familiar with because of its mysterious angle bracketing <> and various wild cards on java generics, but once you understand the purpose of generics in java or Why generics is introduced in Java you will be very comfortable writing code using generic. If you are beginner and not familiar with generic I strongly suggest you put some time and understand the generics and stop writing collection classes without generic. It not only saves you from mischievous ClassCastException but also gives you more readability and deterministic behavior from code.

Generics in java are introduced to enforce type-safety especially on collection classes of java which holds type of Object e.g. ArrayList, HashMap.

Type-safety means compiler will verify type of class during compile time and throw compiler error if it found    improper type. For example if an ArrayList of Gold contains Silver compiler will throw error.
ArrayList<Gold> goldList = new ArrayList<Gold>();
<Gold> tells compiler that this ArrayList must contain only Gold.

Generics can also be used to write parametric classes like Cache<Key, Value> on which type of Key and Value can be specified while creating objects.


Wild Cards used on Generics in Java with Example


There are three wild-cards in generics in Java.

<?>

"?" denotes any unknown type. Use this wild card if you are not sure about Type. for example if you want to have a ArrayList which can work with any type than declare it as  "ArrayList<?> unknownList" and it can be assigned to any type of ArrayList as shown in following example of generics in Java:

ArrayList<?> unknownList = new ArrayList();
unknownList = new ArrayList();
unknownList = new ArrayList();
unknownList = new ArrayList();

<? extends T>

This is little restrictive than previous one it will allow All Types which are either "T" or extends Tmeans subclass of T. for exammple List<? extends Number> can hold List<Number> or List<Integer>

ArrayList<? extends Number> numberList = new ArrayList<Number>();
numberList = new ArrayList<Integer>();
numberList = new ArrayList<Float>();
or
ArrayList<? extends Assets> assetList = new ArrayList<Asset>();
numberList = new ArrayList<Stock>();
numberList = new ArrayList<Gold>();

<T super ?>

This is just opposite of previous one, It will allow T and super classes of T, e.g. List<? super Integer> can hold List<Integer> or List<Number>.

ArrayList<? super Integer> numberList = new ArrayList<Number>();
numberList = new ArrayList<Integer>();
numberList = new ArrayList<Float>(); //compilation error


Advantage of Java Generics:


1) Most important advantage of generics in java is type-safety. Collections prior to JDK1.5 are not type-safe because they accept Object type argument which allows them to catch all type of objects instead of only required type of object. For example if you want to create an ArrayList of Stocks and you don't want that ArrayList also contain any other asset class you can use generics feature of java to create a type-safe collection. Here is an example of using generics to create a type-safe ArrayList

ArrayList<Stocks> stockList = new ArrayList<Stocks>();


Important points of Generics in Java:


2) Generics in Java eliminate ClassCastException while retrieving objects from Collections.remember prior to JDK1.5 if you retrieve objects from Collection you first check for a particular type and then cast, no need to do it now.

ArrayList<Stocks> stockList = new ArrayList<StockList>();
Stock sony = new Stock("Sony","6758.T");
stockList.add(sony);
Stock retreivedStock = stockList.get(sony);

3) A generic Class in Java use formal type parameters to retrieve Type information when instance of generics Class gets created. In below example of generics class in Java <K,V> are formal parameters.

interface Cache <K,V>{
        public V get();
        public V put(K key, V value);
}

As per convention followed on generics version of java collection package we can use

<K, V> for key and value
<T> for type;
<E> for an element of a collection;
 N for number

4) Generics are often related to Templates in C++, though Unlike "Template" in C++, which creates a new type for each specific parametrized type, generics class in Java is only compiled once and more importantly there is just one single class file which is used to create instances for all the specific types.

5) Generics in Java can not only apply on Java Classes but also on methods, so you can write your own generics methods in Java as shown in below example of generics in java:

boolean add(E o)

Here E will be replaced by Actual type parameter when this method will get called.



Generic is very vast topic and there are lot more to be learn to get expertise on java generics. I hope this will serve you a good starting point in terms of reading code written using generic and to get over with complex wild card of generic. Two things I would suggest you to do as beginner first write collection code always using generic and write some  type-safe classes which can accept parameter e.g. type-safe cache Cach<Key, Value>
Previous Post Next Post