by Dinesh Thakur Category: Classes

Generics are used to enforce type-safety in a program. A type-safe program does not have compilation and run-time errors that can result from using incorrect data types.

Recall from our earlier discussion that the ArrayList class is used to create an array to store elements. The size of the array changes automatically as elements are added or removed from it. First, we describe a potential problem with using ArrayList without generics. Let us create an array list as shown here:

ArrayList todoList = new ArrayList();

Suppose that we would like to use this list to keep track of the weekly chores associated with caring for a pet cat. We can add elements to this list using the add method in ArrayList:

todoList.add("Buy gourmet cat food");
todoList.add("See funny cat pictures online");
todoList.add("walk the cat");

All of the elements added to the list are of type String. If you put the above code in the main method and run it, it would run correctly without any errors. Recall, however, that the add method is defined as shown here:

public boolean add(Object obj) - a method that adds the object obj to the end of the list.

Therefore, you able to add an object of any type (say, Box) to todoList using this method:

todoList.add(new Box());

There are two problems with this approach. First, it is odd that a to-do list contains an element that is not of type String. Second-and worse-is that it can cause an error at run time.
Suppose that we would like to display the items in the to-do list. It can do with ArrayList's get method:

public Object get(int index) - a method that returns the element at the given index.

The element returned is of type Object; thus it must be cast back to its original type. A programmer has written this statement to read the fourth item in todoList, expecting it to be of type String:

String s = (String) todoList.get(3);
System.out.println(s);

Running the program now results in the following ClassCastException:

Exception in thread "main" java.lang.ClassCastException:
genericsandcollections.Box cannot be cast to java.lang.String at
genericsandcollections.ListDemo.main(ListDemo.java:14)

The problem is that the fourth element at index 3 is an instance of Box,and it cannot be cast to type String after it is retrieved using the get method. To prevent this error, we will create a list that can only hold elements of type String. This is done as follows:

ArrayList<String> newList = new ArrayList<String>();

Note that we have inserted the type String within angle brackets (<, >). This declaration tells the compiler that newList can only store elements of type String. The advantage of doing this is that if the programmer tried to insert an element of a different type in this list, it would be caught during compilation and thus prevent a run-time error. Generics makes this type of declaration possible. With generics, we can specify the type of elements that will be stored in a particular collection before it is created.

Let us examine the documentation for the ArrayList class with generics. This class is defined to be generic by adding the letter E within angle brackets:

public class ArrayList<E> extends AbstractList<E> implements List<E>,
RandomAccess,Cloneable, Serializable {
// code ..
}

The letter E is a placeholder for the actual element type that will be defined by the programmer. E is known as the type parameter of the ArrayList class. By convention, the type parameter is a single uppercase letter, and is defined to be E for the collection classes. For example, this declares an ArrayList called myPictures that can hold elements of type Picture:

ArrayList<Picture> myPictures;

The type parameter E is replaced by Picture in ArrayList. Here, Picture is called the type argument to the ArrayList class. When you create myPictures, you must again specify that it store elements of type Picture:

myPictures = new ArrayList<Picture>();

The type argument Picture is inserted within angle brackets between ArrayList and the parentheses. Now, myPictures can only hold elements of class Picture (and its subclasses). Note that you cannot create an object of type parameter E because it is not an actual data type.
The type argument can be a class type or interface type, but it cannot be a primitive type. This statement results in a compilation error because it creates an ArrayList with a primitive type argument of int:

ArrayList<int> newList = newArrayList<int>(); // error!

However, you can use a wrapper class, such as Integer, in place of the primitive type.

Generic methods are declared using type parameters. In ArrayList, methods add and get are defined to be generic using the type parameter E:
public boolean add(E e) - a method that adds the element e to the end of the list.
public E get(int index) - a method that returns the element at the specified index in the list.

The methods add and get have a type parameter E instead of Object. After the ArrayList instance has been created, you can use these methods just as you would use any other method in a class. Note that you do not need to cast the value returned by the get method because it is of the data type represented by E and not Object.
To see how the generic methods are called, let us create todoList using genencs:

ArrayList<String> todoList = newArrayList<String>();

This replaces the type parameter E with String in todoList's methods. Therefore, this call to add works correctly:
todoLisLadd("Buy gounnet cat food");
However, the following statement results in a compilation error because add can take only a String argument:
todoList.add(new Box()); // error
The get method retrieves the objects as type String instead of Object:
String s = todoList.get(2);
Note that a cast to String is not needed now because the object retrieved is of type String.





About Dinesh Thakur

Dinesh ThakurDinesh Thakur holds an B.SC (Computer Science), MCSE, MCDBA, CCNA, CCNP, A+, SCJP certifications. Dinesh authors the hugely popular blog. Where he writes how-to guides around Computer fundamental , computer software, Computer programming, and web apps. For any type of query or something that you think is missing, please feel free to Contact us.



Related Articles