Generics classes in Java

In this article, we will discuss how to create Generics classes and what are the rules while defining and using Generics classes

 

Generics Classes:

From Java 1.5 version after Generics concept introduction, a class (POJO) can be defined as follows along with Generics syntax,

GenericsClass.java

package in.bench.resources.generics.example;

public class GenericsClass<T> {

	// member variable
	T t;

	//	1-arg constructor
	public GenericsClass(T t) {
		super();
		this.t = t;
	}

	// getter & setter
	public T getT() {
		return t;
	}

	public void setT(T t) {
		this.t = t;
	}
}

Explanation:

  • Until Java 1.4 version, a class is declared with class identifier followed by class-name and then followed by opening curly-braces ({)
  • After Generics in Java 1.5 version, a class is declared with class identifier followed by class-name along with open angle-bracket (<) & closing angle-bracket (>) and in between them any valid identifier like ‘T’ and it can be anything like E, K, V, abc, xyz, etc.
  • But generally it is declared as T because it is referred as Type-parameter or Parameter-Type. And class-name is referred as Base-type
  • Note: we can declare type-parameter as many as needed depending on the business requirements

 

How to use generics classes:

  • While instantiating a generics class, we are allowed pass either wrapper-types or reference-types like String, Integer or any class or interface
  • Once after instantiating Generics class with that particular type, then generics class behaves very strictly
  • Like, passing String-type to Generics class will replaces type-parameter T with String and it works with that String-type only
  • Similarly, if type-parameter T replaced by either class or interface then Generics class works only with that class or interface only
  • In case, after declaring one type to generics class while instantiating and if we try to work with another type, then compile-time error will be thrown as shown in the 2nd example

 

Example 1: Let us see first example

TestGenerics.java

package in.bench.resources.generics.example;

public class TestGenerics {

	public static void main(String[] args) {

		// 1. instantiate generics class with String-type
		GenericsClass<String> gc1 = new GenericsClass<String>("String-type");
		System.out.println("1. Parameter-type is : " + gc1.getT().getClass().getTypeName());

		// 2. instantiate generics class with Integer-type
		GenericsClass<Integer> gc2 = new GenericsClass<Integer>(245);
		System.out.println("2. Parameter-type is : " + gc2.getT().getClass().getTypeName());

		// 3. instantiate generics class with Float-type
		GenericsClass<Float> gc3 = new GenericsClass<Float>(245.12f);
		System.out.println("3. Parameter-type is : " + gc3.getT().getClass().getTypeName());

		// 4. instantiate generics class with Double-type
		GenericsClass<Double> gc4 = new GenericsClass<Double>(256245.1225);
		System.out.println("4. Parameter-type is : " + gc4.getT().getClass().getTypeName());
	}
}

Output:

1. Parameter-type is : java.lang.String
2. Parameter-type is : java.lang.Integer
3. Parameter-type is : java.lang.Float
4. Parameter-type is : java.lang.Double

 

Example 2: Compile-time error with Generics

  • Once particular Type-parameter is declared for Generics class then it can work only with that type
  • If we try to add or work with any other type, then compile-time error will be thrown
  • For example, if we create generics class object using String-type then setting Double value results in compile-time error as shown in the below screen-capture
  • So, this way type-safety is ensured by Generics feature

 

Rules w.r.t Generics classes:

  • Type-parameter T can be replaced by either wrapper-type or reference-type like class or interface. Trying to define primitive-type for type-parameter T results in compile-time error as shown in the below screen-capture
  • Inheritance relationship applies only for Base-type but not for type-parameter. Trying to define inheritance relationship between type-parameter while instantiating Generics class results in compile-time error as shown in the below screen-capture. Here, Object is a parent-class of String-type but still compile-time error is thrown because parent-child relationship isn’t allowed in type-parameter. Strictly, it should be one type like either String or Object
  • Generics class with different type-parameter aren’t equal. Trying to assign two different type-parameter based same Generics class result in compile-time error as shown in the below screen-capture

 

In the following article, we will discuss Bounded-types which allows to put a range or upper limit to generics classes while instantiating, like defining Number class as upper limit restricts Generics class instantiation to either Number class or one of its sub-class

 

Hope, you found this article very helpful. If you have any suggestion or want to contribute or tricky situation you faced during Interview hours, then share with us. We will include that code here

 

References:

 

Happy Coding !!
Happy Learning !!

Bounded Types in Generics
Introduction to Generics in Java