Skip to main content

Generic Classes in Java

  • Generic classes in Java allow you to define classes, interfaces, and methods with type parameters.

  • This means you can write a single class or method that works with different types of data, providing flexibility and type safety.

  • Generics help avoid runtime errors by catching type-related issues at compile time, making your code more robust and easier to maintain.

Why Use Generic Classes?

  • Type Safety: Ensures that only the specified type is used, preventing runtime errors.

  • Code Reusability: Allows you to write a single class that can handle different types of data.

  • No Casting Needed: Eliminates the need for casting, making the code easier to read and maintain.

  • Compile-Time Checking: Errors are caught at compile time rather than at runtime.

Defining a Generic Class

  • To define a generic class, you use a type parameter inside angle brackets (<>).

  • This type parameter can be used throughout the class to define the type of variables, return types, and method parameters.

Syntax

class ClassName<T> {
// Class body where T can be used as a type
}
  • ClassName is the name of your class.

  • T is a type parameter (you can choose any identifier, but T is common for "Type").

Example of a Generic Class

Let's create a simple generic class called Box that can store objects of any type:

class Box<T> {
private T value;

public void setValue(T value) {
this.value = value;
}

public T getValue() {
return value;
}
}

public class Main {
public static void main(String[] args) {
Box<Integer> intBox = new Box<>();
intBox.setValue(42);
System.out.println("Integer Value: " + intBox.getValue()); // Outputs: 42

Box<String> stringBox = new Box<>();
stringBox.setValue("Hello, Generics!");
System.out.println("String Value: " + stringBox.getValue()); // Outputs: Hello, Generics!
}
}

Explanation

  • Generic Class Definition: class Box<T> defines a generic class Box with a type parameter T.

  • Field: private T value; declares a field of type T.

  • Methods:

  1. public void setValue(T value): This method sets the value of type T.
  2. public T getValue(): This method returns the value of type T.

Using the Generic Class

  • Creating Instances:
  1. Box<Integer> intBox = new Box<>(); creates an instance of Box that can hold an Integer.
  2. Box<String> stringBox = new Box<>(); creates an instance of Box that can hold a String.
  • Setting Values:
  1. intBox.setValue(42); sets the value of intBox to 42.
  2. stringBox.setValue("Hello, Generics!"); sets the value of stringBox to "Hello, Generics!".
  • Getting Values:
  1. System.out.println("Integer Value: " + intBox.getValue()); retrieves and prints the value from intBox.
  2. System.out.println("String Value: " + stringBox.getValue()); retrieves and prints the value from stringBox.

Generic Classes with Multiple Type Parameters

You can define a generic class with multiple type parameters. For example, a Pair class that holds two values of different types:

class Pair<K, V> {
private K key;
private V value;

public Pair(K key, V value) {
this.key = key;
this.value = value;
}

public K getKey() {
return key;
}

public V getValue() {
return value;
}
}

public class Main {
public static void main(String[] args) {
Pair<Integer, String> pair = new Pair<>(1, "One");
System.out.println("Key: " + pair.getKey() + ", Value: " + pair.getValue()); // Outputs: Key: 1, Value: One
}
}

Explanation

  • Multiple Type Parameters: class Pair<K, V> defines a generic class Pair with two type parameters K and V.

  • Constructor: The constructor public Pair(K key, V value) initializes the key and value.

  • Methods:

  1. public K getKey(): This method returns the key of type K.
  2. public V getValue(): This method returns the value of type V.

Benefits of Generic Classes

  • Type Safety: The compiler ensures that only the specified type is used, preventing runtime type errors.

  • Code Reusability: Generic classes allow you to create flexible and reusable code without duplicating logic for different types.

  • Elimination of Casting: With generics, you don’t need to cast objects when retrieving them, making the code cleaner and safer.

  • Compile-Time Checking: Generics provide compile-time type checking, catching errors early in the development process.

Summary

  • Generic classes in Java provide a powerful way to create flexible, reusable, and type-safe code.

  • By using type parameters, you can define classes that work with any data type while ensuring type safety and eliminating the need for casting.

  • Generics enhance code clarity, maintainability, and robustness by catching type-related errors at compile time.

Understanding generic classes is essential for writing modern, efficient Java applications.