Generics enable types (classes and interfaces) to be parameters when defining classes, interfaces and methods. Much like the more familiar formal parameters used in method declarations, type parameters provide a way for you to re-use the same code with different inputs. The difference is that the inputs to formal parameters are values, while the inputs to type parameters are types.
The collections classes such as the List class can be generalized so that only collections of that type are accepted in the application. An example of the generalized ArrayList is shown below. What the following statement does is that it only accepts list items which are of the type string −
List<String> list = new ArrayList<String>();
In the following code example, we are doing the following −
class Example { static void main(String[] args) { // Creating a generic List collection List<String> list = new ArrayList<String>(); list.add("First String"); list.add("Second String"); list.add("Third String"); for(String str : list) { println(str); } } }
The output of the above program would be −
First String Second String Third String
The entire class can also be generalized. This makes the class more flexible in accepting any types and working accordingly with those types. Let’s look at an example of how we can accomplish this.
In the following program, we are carrying out the following steps −
We are creating a class called ListType. Note the <T> keywords placed in front of the class definition. This tells the compiler that this class can accept any type. So when we declare an object of this class, we can specify a type during the the declaration and that type would be replaced in the placeholder <T>
The generic class has simple getter and setter methods to work with the member variable defined in the class.
In the main program, notice that we are able to declare objects of the ListType class, but of different types. The first one is of the type Integer and the second one is of the type String.
class Example { static void main(String[] args) { // Creating a generic List collection ListType<String> lststr = new ListType<>(); lststr.set("First String"); println(lststr.get()); ListType<Integer> lstint = new ListType<>(); lstint.set(1); println(lstint.get()); } } public class ListType<T> { private T localt; public T get() { return this.localt; } public void set(T plocal) { this.localt = plocal; } }
The output of the above program would be −
First String 1