Understanding Generics in Java
1. Introduction
Generic means applicable or referring to a whole class or a group. In Java, Generics was introduced in J2SE 5.0, primarily to provide compile time safety, thereby keeping us away from the possibilities of ClassCastException to a great extent, at the compile time itself.
Let’s take an example of Collections in Java. Before Generics, we stored objects of any type into a collection, such as an ArrayList. With Generics, we are forced to store the objects only of a particular type.
2. Understanding Generics
Let us understand Generics with a real life example. Let’s say we have a “Box” which has already labelled with the name “Fruits” then you can put only fruits in that box. But if you remove the label from a “Box” then it can be used to put different types of things e.g. fruits, vegetables etc. So labeling the box as Fruits, we are adding a restriction to add only fruits into the box. This way we are using Generics to save the mess.
Similarly, we can label different rack spaces at our homes as Kitchen Rack or a Shoe Rack, so someone won’t ever add a utensil on a Show Rack.
3. Benefits of Using Generics in Java
- Type Safety – We can hold only a single type of objects in Generics. It will not allow another objects, such as in a Collection such that List<String> will allow only String objects to be added.
- No Type Casting – There is no need for the type casting of the objects. For example, without generics, we explicitly need to typecast to the required type.
123List list = new ArrayList();list.add("hello");String s = (String) list.get(0); // typecasting
With Generics, we don’t need to typecast any more.
123List<String> list = new ArrayList<String>();list.add("hello");String s = list.get(0); - Compile Time Check – Error will be thrown at the compile-time itself so it avoids error during runtime which are difficult to find and saves our time. It is often known to be a good programming practice to handle the errors at compile-time itself.
4. Generic Methods
To create a Generic method we need to take care of the following rules –
- Method declarations should have a Type Parameter section delimited by angle brackets (< and >) that precedes the method’s return type.
- Every Type Parameter section can contain one or more than one Type Parameters.
- The Type Parameter can also be used to declare the return type.
- You can create generic method body similar to any normal method. One thing to be noted that Type Parameters cannot be primitive types. (Refer to the below example)
For example –
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
class GenericsDemo1 { public static <E> void displayElements(E[] elements) { for (E element : elements) { System.out.println(element); } System.out.println(); } public static void main(String args[]) { Integer[] intArray = { 10, 20, 30 }; Character[] charArray = { 'J', 'A', 'V', 'A' }; System.out.println("Integer Array: "); displayElements(intArray); System.out.println("Character Array: "); displayElements(charArray); } } |
Executing the above class as a java application will display the following output –
1 2 3 4 5 6 7 8 9 10 |
Integer Array: 10 20 30 Character Array: J A V A |
5. Generic Class
A Generic Class can refer to a class of any Type (String, Employee, Integer, etc.).
For example –
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
class GenericClass<T> { T obj; void set(T obj) { this.obj = obj; } T get() { return obj; } } class GenericsDemo2 { public static void main(String args[]) { GenericClass<String> m = new GenericClass<String>(); m.set("jcombat"); System.out.println(m.get()); } } |
T Type Parameter in the above example is used to create the generic class of a specific type, which is String in our case.
Executing the above class as a java application will display the following output –
1 |
jcombat |