Introduction
A generic class in Java allows you to define a class with type parameters, making the class more flexible and reusable. Generics provide compile-time type safety, eliminating the need for type casting and reducing runtime errors.
Table of Contents
- What is a Generic Class?
- Defining a Generic Class
- Benefits of Using Generic Classes
- Creating Instances of a Generic Class
- Example: Simple Generic Class
- Bounded Type Parameters in Generic Classes
- Example: Generic Class with Bounded Type Parameters
- Type Erasure
- Restrictions on Generic Classes
- Conclusion
1. What is a Generic Class?
A generic class is a class that can operate on objects of various types while providing compile-time type safety. You define a generic class with one or more type parameters, which can be used throughout the class for various purposes.
2. Defining a Generic Class
A generic class is defined by placing the type parameter(s) inside angle brackets (<>
) after the class name.
Syntax:
class ClassName<T> {
// Class body
}
3. Benefits of Using Generic Classes
- Type Safety: Generic classes ensure that the type of objects passed to and returned by the class is consistent, reducing runtime errors.
- Code Reusability: A single generic class can be used with different types, reducing code duplication.
- Elimination of Type Casting: Explicit type casting is not needed when using generic classes.
4. Creating Instances of a Generic Class
To create an instance of a generic class, you need to specify the type argument in angle brackets.
Example:
GenericClass<Integer> intObj = new GenericClass<>();
GenericClass<String> strObj = new GenericClass<>();
5. Example: Simple Generic Class
Example:
// Defining a simple generic class
class GenericBox<T> {
private T value;
public void setValue(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
public class GenericClassExample {
public static void main(String[] args) {
// Creating an instance of a generic class for Integer type
GenericBox<Integer> intBox = new GenericBox<>();
intBox.setValue(100);
System.out.println("Integer Value: " + intBox.getValue());
// Creating an instance of a generic class for String type
GenericBox<String> strBox = new GenericBox<>();
strBox.setValue("Java Generics");
System.out.println("String Value: " + strBox.getValue());
}
}
Output:
Integer Value: 100
String Value: Java Generics
Explanation:
- The
GenericBox
class is defined with a type parameterT
. - The
setValue
andgetValue
methods use the type parameterT
. - Instances of
GenericBox
are created forInteger
andString
types.
6. Bounded Type Parameters in Generic Classes
You can restrict the types that can be used as type arguments by using bounded type parameters. Bounded type parameters allow you to specify that a type must be a subclass (or implementor) of a specific class (or interface).
Syntax:
class ClassName<T extends SuperClass> {
// Class body
}
7. Example: Generic Class with Bounded Type Parameters
Example:
// Defining a generic class with a bounded type parameter
class NumberBox<T extends Number> {
private T value;
public void setValue(T value) {
this.value = value;
}
public T getValue() {
return value;
}
public double getDoubleValue() {
return value.doubleValue();
}
}
public class BoundedGenericClassExample {
public static void main(String[] args) {
// Creating an instance of a generic class for Integer type
NumberBox<Integer> intBox = new NumberBox<>();
intBox.setValue(100);
System.out.println("Integer Value: " + intBox.getValue());
System.out.println("Double Value: " + intBox.getDoubleValue());
// Creating an instance of a generic class for Double type
NumberBox<Double> doubleBox = new NumberBox<>();
doubleBox.setValue(123.45);
System.out.println("Double Value: " + doubleBox.getValue());
System.out.println("Double Value: " + doubleBox.getDoubleValue());
}
}
Output:
Integer Value: 100
Double Value: 100.0
Double Value: 123.45
Double Value: 123.45
Explanation:
- The
NumberBox
class is defined with a bounded type parameterT extends Number
. - The
setValue
,getValue
, andgetDoubleValue
methods use the type parameterT
. - Instances of
NumberBox
are created forInteger
andDouble
types.
8. Type Erasure
Type erasure is a process by which the compiler removes all information related to generic type parameters and replaces them with their bounds or Object
if the type parameter is unbounded. This ensures compatibility with older versions of Java that do not support generics.
Example:
public class TypeErasureExample<T> {
private T value;
public void setValue(T value) {
this.value = value;
}
public T getValue() {
return value;
}
public static void main(String[] args) {
TypeErasureExample<Integer> intBox = new TypeErasureExample<>();
intBox.setValue(100);
System.out.println("Integer Value: " + intBox.getValue());
TypeErasureExample<String> strBox = new TypeErasureExample<>();
strBox.setValue("Java Generics");
System.out.println("String Value: " + strBox.getValue());
}
}
Explanation:
- During compilation, the generic type
T
is erased and replaced withObject
or the upper bound specified.
9. Restrictions on Generic Classes
There are several restrictions on generic classes in Java:
-
Cannot Instantiate Generic Types with Primitive Types:
// This is not allowed GenericClass<int> intObj = new GenericClass<>();
-
Cannot Create Instances of Type Parameters:
class GenericClass<T> { // This is not allowed // T obj = new T(); }
-
Cannot Declare Static Fields Whose Types are Type Parameters:
class GenericClass<T> { // This is not allowed // static T obj; }
-
Cannot Use Casts or instanceof with Parameterized Types:
class GenericClass<T> { // This is not allowed // if (obj instanceof T) { } // T[] array = (T[]) new Object[10]; }
-
Cannot Create Arrays of Parameterized Types:
// This is not allowed GenericClass<String>[] stringArray = new GenericClass<String>[10];
10. Conclusion
Generic classes in Java provide a powerful mechanism to write flexible, reusable, and type-safe code. By using type parameters, you can create classes that can operate on objects of various types, ensuring type safety and reducing the need for type casting. Bounded type parameters further enhance the flexibility of generic classes by allowing you to specify constraints on the types that can be used as arguments.
By understanding and utilizing generic classes, you can create more robust and maintainable Java applications.
Happy coding!
Comments
Post a Comment
Leave Comment