Generic types in Java

Now we have some knowledge of Generics in Java. So, we should start exploring other important concepts revolving around generics. We will discuss the Java generic type.

1. Generic class
2. How to create a generic class?
3. Generic method
4. Generic Interface

1. Generic class

Without generic, A class that can refer to any type of data. When you create a class, it can accept any type of data. Let’s understand with an example:  

class Example
{
   private Object obj;
 
   public void set(Object t) { this.obj = t; }
    
   public Object get() { return obj; }
   
   public static void main(String arg[])
   {
	   Example exampleOne = new Example();
	   exampleOne.set(123);
	   Integer intValue = (Integer)exampleOne.get();
	   System.out.println(intValue);
	   
	   Example exampleTwo = new Example();
	   exampleTwo.set("Hello");
	   Integer intValueTwo = (Integer)exampleTwo.get();
	   System.out.println(intValueTwo);
   }
}

Output: 123
Exception in thread “main” java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Integer (java.lang.String and java.lang.Integer are in module java.base of loader ‘bootstrap’)
at Example.main(Example.java:18)

It throwing a ClassCastException because we are casting String to Integer. To resolve the problem of runtime exception we can use generic class. That will accept only one type of data.

Let’s say you want to initialize the class with a certain type. It means the class should be used for only one type. So, you can make it a generic class. The generic class can take the object of a specific type. It is part of Java generic type.

How to create a generic class?

We use <T> to specify parameter types in generic class creation. By use of <T>, you can make a class of specific types.

class Example<T> 
{
   private T obj;
 
   public void set(T t) { this.obj = t; }
    
   public T get() { return obj; }
}
class Example<T> 
{
   private T obj;
 
   public void set(T t) { this.obj = t; }
    
   public T get() { return obj; }
}

public class Student
{
	public static void main(String arg[])
	{
		Example<Integer> example = new Example<Integer>();
		example.set(1);
		example.add("JavaGoal"); //Compile time error  
		System.out.println(example.get());  
	}
}

Output: Exception in thread “main” java.lang.Error: Unresolved compilation problem: The method add(String) is undefined for the type Example<Integer> at Student.main(Student.java:16)

In the above example, we want the object of the class to hold the value of String type only. So, when we trying to add an object of Integer it is showing compilation error. It applies the restriction to the programmer, So that programmer can add only one type of data and ignore the run time exception. By the use of generic, the compiler shows the errors at compile time rather than the run time. It saves the programmer time because it’s difficult to find the error on runtime. Its always better to find the errors at compile time rather than the run time.

class Test<T1, T2> 
{ 
    T1 obj1;  // An object of type T1 
    T2 obj2;  // An object of type U2 
  
    public void setData(T1 object1, T2 object2)
    {
    	obj1 = object1;
    	obj2 = object2;
    }
    
    // To print objects of T1 and T2 
    public void print() 
    { 
        System.out.println(obj1); 
        System.out.println(obj2); 
    } 
} 
  
class MainClass 
{ 
    public static void main (String[] args) 
    { 
        Test<String, Integer> test = new Test<String, Integer>(); 
        test.setData("Hello", 123);
        test.print(); 
    } 
}

Output: Hello
123

Onward java 5, Collection framework supports the generic concept. You can see the example of ArrayList.

import java.util.ArrayList;  
class ExampleOfGeneric
{  
	public static void main(String args[])
	{  
		ArrayList<String> listOfNames = new ArrayList<String>();  
		listOfNames.add("JAVA");  
		listOfNames.add("GOAL");  
		//list.add(123);//compile time error  
		  
		for (String s : listOfNames) 
		{
			System.out.println(s);
		}	
	}  
}

Output: JAVA
GOAL

2. Generic method

We can create a generic method that can accept any type of argument. These are similar to the generic class but In the Generic method, the scope of the parameter is within the method.

public class Example
{
	public <T> void printData(T data)
	{
		System.out.println("Data is = "+ data);
	}
	public <T> T checkData(T data)
	{
		return data;
	}
	
	public static void main(String arg[])
	{
		Example obj = new Example();
		// Using int as parameter
		obj.checkData(1);
		obj.printData(1);
		
		// Using String as parameter
		obj.checkData("JAVAGOAL");
		obj.printData("JAVAGOAL");
	}
}

Output: Data is = 1
Data is = JAVAGOAL

In the above example, we created to the method of the generic type. Both can take any type of data. We are proving int and String data as a parameter to generic methods.

3. Generic Interface

Like a generic class, Let’s say you want to initialize the Interface with a certain type. It means the Interface should be used for only one type. So, you can make it a generic Interface. The generic interface can take an object of a specific type. You can create a generic interface by use <T> to specify parameter types in generic Interface creation.

//Generic interface definition
interface ExampleInterface<T> 
{
   public void ShowDataCal(T t);
}
 
//A class implementing generic interface
class DemoClass implements ExampleInterface<String>
{
   public void ShowDataCal(String t)
   {
      //some code
   }
}

You can take the example of a Comparable interface. It is the best example of Generics in interfaces.

public interface Comparable<T> {
    public int compareTo(T o);
}

Leave a Comment