Java Programming Handbook

    Bounds on Generics in Java

    Introduction#

    In the previous blog, we learned how to define Generic Classes in Java. While generics allow flexibility, sometimes we need to restrict the type parameters to specific types. This is where bounded type parameters come into play.

    In this blog, we will cover:

    • What are Bounded Type Parameters?
    • Upper Bounds (extends keyword)
    • Lower Bounds (super keyword)
    • Why and When to Use Bounds?
    • Examples

    What are Bounded Type Parameters?#

    By default, a generic type parameter (T) can be any type. But in some cases, we may want to limit T to only certain types (e.g., only Number or its subclasses). This is called bounding a type parameter.

    🔹 Syntax for Upper Bound

    class ClassName<T extends SuperClass> { }

    Here, T can be SuperClass or any subclass of SuperClass.

    🔹 Syntax for Lower Bound

    className<? super SubClass>

    Here, ? can be SubClass or any superclass of SubClass.

    Upper Bounded Wildcards (extends Keyword)#

    Upper bounds restrict the type parameter to a specific class and its subclasses.

    Example 1: Restricting Type to Number or Subclasses#

    class Calculator<T extends Number> { private T num; public Calculator(T num) { this.num = num; } public double getDoubleValue() { return num.doubleValue(); } } public class UpperBoundExample { public static void main(String[] args) { Calculator<Integer> intCalc = new Calculator<>(10); Calculator<Double> doubleCalc = new Calculator<>(10.5); System.out.println("Integer value as double: " + intCalc.getDoubleValue()); System.out.println("Double value: " + doubleCalc.getDoubleValue()); } }

    ✅ This ensures that Calculator only accepts Number types (Integer, Double, Float, etc.).

    Lower Bounded Wildcards (super Keyword)#

    Lower bounds restrict the type parameter to a specific class and its superclasses.

    🔹 Useful when we want to ensure the type is of a certain minimum type.

    Example 2: Restricting Type to Integer or Its Superclasses#

    import java.util.List; public class LowerBoundExample { public static void addNumbers(List<? super Integer> list) { list.add(10); list.add(20); } public static void main(String[] args) { List<Number> numbers = new java.util.ArrayList<>(); addNumbers(numbers); System.out.println(numbers); } }

    ✅ This ensures we can add Integer values while keeping flexibility for Number or Object.

    Why and When to Use Bounds?#

    🔹 Upper Bounds (extends)

    • When you need to ensure the type belongs to a specific hierarchy.
    • Example: A method that operates on numbers should only accept Number or its subclasses.

    🔹 Lower Bounds (super)

    • When you need flexibility in handling a range of types, including parent classes.
    • Example: Adding elements to a list while keeping broader compatibility.

    Conclusion#

    In this blog, we learned:

    • How to restrict generic types using bounds.
    • How to use Upper Bounded (extends) and Lower Bounded (super) wildcards.
    • Why bounds are useful in real-world applications.

    Bounds help control type flexibility while maintaining type safety in Java.

    Last updated on Apr 09, 2025