Curriculum
Course: Learn Java Programming
Login

Curriculum

Learn Java Programming

Text lesson

Overview of Generics in Java

[post-views]

 

In this lesson, you will learn.

  • What are Generics
  • Advantages of Generics
  • What is the Need for Generics
  • Using Generics: Examples
  • Generic Class With Two Parameter Type
  • Examples

 

1. What are Generics?

  1. The term Generics means parameterized types.
  2. Using Generics, it is possible to create a single class, interface, and method that can be used with different types of data(objects) within the Generics domain.
  3. A class, interface, or method that operates on a parameterized type is called Generic, as in a Generic class or Generic method.

 

Generics were introduced to Java in JDK 5.0.

 

2. Advantages of Generics

  • Code Reusability — The common Java code can be used with multiple object types.
  • Compile-Time Safety — Java checks the generics code at the compile time against errors instead of at runtime.
  • Type Safety — We can restrict adding unnecessary data
  • Usage in Collections — Collections need object types to deal with data

 

Generics enable stronger type checks at compile time and can be used to develop robust and reusable code components.

 

3. Need of Generics

For example, you would like to print the Numbers and Text using a Printer class.

Using a traditional approach, we will have to create 2 classes since we have 2 types of data i.e. Number(Integer) and Text(String).

 

Create a class NumberPrinter for Printing Numbers

public class NumberPrinter {
    private final Integer value;

    public NumberPrinter(Integer value) {
        this.value = value;
    }

    public void printData() {
        System.out.println("Printing: " + value);
    }
}

 

Create a class TextPrinter for Printing Text Data

public class TextPrinter {
    private final String value;

    public TextPrinter(String value) {
        this.value = value;
    }

    public void printData() {
        System.out.println("Printing: " + value);
    }
}

 

Creating a Driver Class i.e. Printer

public class Printer {
    public static void main(String[] args) {
        NumberPrinter numberObj = new NumberPrinter(10);
        numberObj.printData(); // output = print: 10
        TextPrinter textObj = new TextPrinter("Learning Generics");
        textObj.printData();   // output = print: Learning Generics
    }
}

 

Here, you can see, there is a code duplication due to only a change in the data types(Integer and String). So, here the data type is only the difference!

So, let’s understand the concept of Generics to avoid code duplication.

 

4. Using Generics

Let’s implement the above example using a Generic Printer class.

public class Printer<T> {
    private final T value;

    public Printer(T value) {
        this.value = value;
    }

    public void printData() {
        System.out.println("Printing: " + value);
    }
}

 

To use this Printer class for different types, you simply instantiate it with the desired data type.

Printer<Integer> integerPrinter = new Printer<>(15);
integerPrinter.printData();   // output = print: 15

Printer<String> stringPrinter = new Printer<>("Learning Generics");
stringPrinter.printData();   // output = print: Learning Generics

 

Explanation

Here, Only one class (Printer) is required to print different data types.

Printer<T>: Here, T is the name of a type parameter contained within the angle bracket (< >) that can be used to declare a type as a common standard.

This name is used as a placeholder for the actual type that will be passed to the Printer when an object is created.

We can create the Printer objects for other data types also like Double/Long. So, the Code reusability is achieved in style.

Printer(T value): This will accept a value of type T (any type). Whatever type is specified for an instance of Printer.

 

Example 1: Generic Box Class

package genericclass;

public class Box<T> {
    private T t; // T stands for "Type"

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

    public T get() {
        return t;
    }

    public static void main(String[] args) {
        Box<Integer> integerBox = new Box<>();
        integerBox.set(10);
        System.out.println("Box contains: " + integerBox.get());

        Box<String> stringBox = new Box<>();
        stringBox.set("Hello World");
        System.out.println("Box contains: " + stringBox.get());
    }
}

 

Output

Box contains: 10
Box contains: Hello World

 

Explanation: The Box class is a generic container for different types of objects. By specifying the type parameter <T>, it can safely hold any type, ensuring type safety and reducing the need for casts.

 

Example 2: Display Array Elements

package genericclass;

public class ArrayPrinter<T> {
	
    public void printArray(T[] array) {
        for (T element : array) {
            System.out.print(element + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        ArrayPrinter<String> stringPrinter = new ArrayPrinter<>();
        stringPrinter.printArray(new String[]{"Hello", "World"});

        ArrayPrinter<Integer> integerPrinter = new ArrayPrinter<>();
        integerPrinter.printArray(new Integer[]{1, 2, 3, 4});
    }
}

 

Output

Hello World 
1 2 3 4 

 


5. A Generic Class With Two Type Parameters

Generic classes can accept multiple types also, as demonstrated in the example where it can accept both Integer and String.

 

Example: A Generic Class With Two Type Parameters

The following example accepts both Integer and String.

public class MultiPrinter<T, V> {
    private final T value1;
    private final V value2;

    public MultiPrinter(T value1, V value2) {
        this.value1 = value1;
        this.value2 = value2;
    }

    public void printValue() {
        System.out.println("print: " +value1 + " : " + value2);
    }
}

//Using this class
MultiPrinter<Integer, String> multiPrinter = new MultiPrinter<>(15, "Hi");
multiPrinter.printValue(); // output = print: 15 : Hi

 

Important Point!

Generics Work Only with Reference Types

When declaring an instance of a generic type, the type argument passed to the type parameter must be a reference type.

You cannot use a primitive type, such as int or char.

Printer<int> intOb = new Printer<int>(53); 
// Error, can't use primitive type

 

 

Java Type Naming conventions

  • E — Element (used in Collections)
  • K — Key (Used in Map)
  • N — Number
  • T — Type
  • V — Value (Used in Map)
  • S, U, V, etc. — 2nd, 3rd, 4th types

 

 

 

 

 

 


 

End of the lesson….enjoy learning

 

 

Student Ratings and Reviews

 

 

 

There are no reviews yet. Be the first one to write one.

 

 

Submit a Review