Bounded Type Parameters
Bounded type parameters in Java
Bounded type parameters in Java generics allow you to restrict the types that can be used as arguments for a type parameter.
By specifying a bound, you ensure that the type parameter must be a subtype of a particular class or implement a particular interface.
This adds flexibility while maintaining type safety and providing more control over the types that can be used.
Defining Bounded Type Parameters
You can define a bounded type parameter by using the extends keyword to specify an upper bound. This means the type parameter must be a subtype of the specified class or implement the specified interface.
Syntax
class ClassName<T extends SuperClass> {
// Class body where T can be used as a type
}
ClassName is the name of your class.
T is a type parameter that must be a subtype of SuperClass.
You can also define multiple bounds using the & symbol:
class ClassName<T extends ClassA & InterfaceB> {
// Class body where T can be used as a type
}
Example of Bounded Type Parameters
Let's create a simple example where we have a generic method that finds the maximum value between two values.
The type parameter is bounded by the Comparable interface, ensuring that the elements can be compared to each other.
public class Main {
// Generic method to find the maximum of two values
public static <T extends Comparable<T>> T findMax(T value1, T value2) {
return value1.compareTo(value2) > 0 ? value1 : value2;
}
public static void main(String[] args) {
Integer int1 = 42;
Integer int2 = 55;
String str1 = "apple";
String str2 = "orange";
System.out.println("Max Integer: " + findMax(int1, int2)); // Outputs: Max Integer: 55
System.out.println("Max String: " + findMax(str1, str2)); // Outputs: Max String: orange
}
}
Explanation
Generic Method Definition:
public static <T extends Comparable<T>> T findMax(T value1, T value2)
defines a generic method findMax with a bounded type parameter T.Bounded Type Parameter:
<T extends Comparable<T>>
ensures that T must implement the Comparable interface.Method Body:
The method compares value1 and value2 using the compareTo method from the Comparable interface.
Returns the greater value.
Bounded Type Parameters in Generic Classes
You can also use bounded type parameters in generic classes. For example, let's create a Box class that can only hold objects that are instances of Number or its subclasses:
class Box<T extends Number> {
private T value;
public void setValue(T value) {
this.value = value;
}
public T getValue() {
return value;
}
public double doubleValue() {
return value.doubleValue();
}
}
public class Main {
public static void main(String[] args) {
Box<Integer> intBox = new Box<>();
intBox.setValue(42);
System.out.println("Box value: " + intBox.getValue()); // Outputs: Box value: 42
System.out.println("Double value: " + intBox.doubleValue()); // Outputs: Double value: 42.0
Box<Double> doubleBox = new Box<>();
doubleBox.setValue(3.14);
System.out.println("Box value: " + doubleBox.getValue()); // Outputs: Box value: 3.14
System.out.println("Double value: " + doubleBox.doubleValue()); // Outputs: Double value: 3.14
}
}
Explanation
Generic Class Definition:
class Box<T extends Number>
defines a generic class Box with a bounded type parameter T.Bounded Type Parameter:
<T extends Number>
ensures that T must be a subclass of Number.Methods:
setValue(T value): Sets the value of type T.
getValue(): Returns the value of type T.
doubleValue(): Returns the double value of T using the doubleValue() method from the Number class.
Summary
Bounded type parameters restrict the types that can be used as arguments for a type parameter.
They ensure type safety, flexibility, and code reusability.
Bounded type parameters provide compile-time checking, preventing runtime errors.
Use the extends keyword to define a bounded type parameter.
You can also define multiple bounds using the & symbol.
Understanding bounded type parameters is essential for writing modern, efficient Java applications.