Generics

Generics were introduced in the JDK 5.0 as a language enhancement. Generics are heavily used Java Collection Framework interface. Generics can be used to define methods, classes and interfaces that can operate with different data types.

Why Use Generics

  1. Generics provide compile-time safety
  2. Removes unnecessary type conversions

Generic Interfaces

Generics are defined with the type in angle brackets, <> after the interface name.

Here is the definition of the java.util.Collection interface

public interface Collection<E> extends Iterable<E>

<E> defines the generic element that can passed to the Collection. The collection can be used as follows to define a collection that can only contain String types :

Collection<String> collection;

or a collection that holds Integer types as follows :

Collection<Integer> collection;

We can replace <E> in Collection<E> with any type. We gain compile type safety checks from the compiler and also remove type conversion since we know the collection will always contain a specific type.

Generic Classes

Generic classes are defined the same way as generic interfaces. The type is specified in angle brackets, <>.

Any ArrayList is an ordered collection of objects by their index. Here is the definition of the ArrayList generic class :

public class ArrayList<E> extends AbstractList<E> implements List<E>

Notice how the the class is defined with the <E>, ArrayList<E> and also inherits from a generic class and a generic interface. The <E> defines the ArrayList to be generic. It represents any element type. We can replace <E> with any data type. Here is how we can declare a variable of the ArrayList to hold Integer types :

ArrayList<Integer> list;

and to hold String types :

ArrayList<String> list;

Instantiating Generic Classes

When instantiating a generic class we have to include the type in angle brackets, <>.

Here is an example of instantiating the generic ArrayList from above with types of String :

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

Since we have already defined the type to be a generic String, we can replace the new ArrayList<String>() with new ArrayList<>(), since its redundant as follows :

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

We could also define an ArrayList that can hold Integer types :

ArrayList<Integer> list = new ArrayList<>();

Using Generic Methods

Methods can also be declared to be generic by using the same E specified in the generic class.

Here is the definition of the generic method add in the ArrayList class :

public boolean add(E e){}

To use the generic method add, we will have to pass in the correct type of E.

ArrayList<Integer> list = new ArrayList<>();
list.add(10);
list.add(15.9); // compile type error

Notice the above generates a compile-time error when we try to pass in the wrong type. Without using generics the following will work :

ArrayList list = new ArrayList<>();
list.add(10);
list.add(15.9); // works without an error

The above works because we did not limit the types the ArrayList can hold. The ArrayList hold types of Object. This code can cause run-time errors in future since we did not guarantee the types in the ArrayList.

results matching ""

    No results matching ""