Java Generics: extends Keyword

Introduction

The extends keyword in Java Generics is used to create upper bounded wildcards and bounded type parameters. This allows you to specify that a type parameter or wildcard must be a subclass (or implementor) of a specific class (or interface). Using extends helps to ensure type safety and provides flexibility when writing generic code.

Table of Contents

  1. What are Upper Bounded Wildcards?
  2. Syntax of Upper Bounded Wildcards
  3. Example: Upper Bounded Wildcards
  4. What are Bounded Type Parameters?
  5. Syntax of Bounded Type Parameters
  6. Example: Bounded Type Parameters
  7. Use Cases for extends in Generics
  8. Conclusion

1. What are Upper Bounded Wildcards?

Upper bounded wildcards restrict the unknown type to be a specific type or a subtype of that type. This is useful when you want to read items from a structure and perform operations on them, while ensuring that they are of a certain type or its subtype.

2. Syntax of Upper Bounded Wildcards

The syntax for upper bounded wildcards is to use the extends keyword followed by the upper bound type within angle brackets (<>).

Syntax:

List<? extends Type> list = new ArrayList<>();

3. Example: Upper Bounded Wildcards

Example:

import java.util.List;
import java.util.ArrayList;

public class UpperBoundedWildcardExample {
    // Method to calculate the sum of a list of numbers
    public static double sumOfList(List<? extends Number> list) {
        double sum = 0.0;
        for (Number number : list) {
            sum += number.doubleValue();
        }
        return sum;
    }

    public static void main(String[] args) {
        List<Integer> intList = new ArrayList<>();
        intList.add(1);
        intList.add(2);
        intList.add(3);

        List<Double> doubleList = new ArrayList<>();
        doubleList.add(1.1);
        doubleList.add(2.2);
        doubleList.add(3.3);

        System.out.println("Sum of intList: " + sumOfList(intList));
        System.out.println("Sum of doubleList: " + sumOfList(doubleList));
    }
}

Output:

Sum of intList: 6.0
Sum of doubleList: 6.6

Explanation:

  • The sumOfList method accepts a list of any type that extends Number. This means the list can contain Integer, Double, Float, etc.
  • The method iterates through the list, treating each element as a Number and summing their double values.
  • In the main method, two lists (intList and doubleList) are created and populated with integers and doubles, respectively. The sumOfList method is called with each list, demonstrating that it can handle both Integer and Double types.

4. What are Bounded Type Parameters?

Bounded type parameters allow you to restrict the types that can be used as type arguments in a generic class, interface, or method. They ensure that the type parameter must be a specific type or its subtype, providing more control and type safety.

5. Syntax of Bounded Type Parameters

The syntax for bounded type parameters is to use the extends keyword followed by the upper bound type within angle brackets (<>).

Syntax:

class ClassName<T extends SuperClass> {
    // Class body
}

6. Example: Bounded Type Parameters

Example:

// Defining a generic class with a bounded type parameter
class Box<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 BoundedTypeParameterExample {
    public static void main(String[] args) {
        Box<Integer> intBox = new Box<>();
        intBox.setValue(100);
        System.out.println("Integer Value: " + intBox.getValue());
        System.out.println("Double Value: " + intBox.getDoubleValue());

        Box<Double> doubleBox = new Box<>();
        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 Box class is defined with a bounded type parameter T extends Number.
  • The setValue, getValue, and getDoubleValue methods use the type parameter T.
  • Instances of Box are created for Integer and Double types.

7. Use Cases for extends in Generics

  • Reading from a Collection: When you want to read elements from a collection and perform operations on them, using an upper bounded wildcard ensures that the elements are of a specific type or its subtype.
  • Generic Algorithms: Upper bounded wildcards and bounded type parameters are useful in generic algorithms that need to operate on elements of a certain type or its subtypes.
  • Type Safety: They help ensure type safety by restricting the types that can be used as arguments, preventing potential runtime errors.

8. Conclusion

The extends keyword in Java Generics provides a powerful way to write flexible and type-safe code. By specifying that a type parameter or wildcard must be a specific type or a subtype of that type, you can ensure that your methods and classes can safely operate on the elements. Understanding and using upper bounded wildcards and bounded type parameters can enhance the robustness and reusability of your Java programs.

Happy coding!

Comments