Understanding Cannot be Converted to java.util.Collection<? extends ...>

In Java, the type system is a powerful feature that helps catch many errors at compile - time. One common error message developers encounter is cannot be converted to java.util.Collection<? extends …>. This error typically arises when working with generics and collections, and understanding its root causes, typical usage scenarios, and how to avoid common pitfalls is crucial for writing robust Java code.

Table of Contents

  1. Core Concepts
  2. Typical Usage Scenarios
  3. Common Pitfalls
  4. Best Practices
  5. Code Examples
  6. Conclusion
  7. FAQ
  8. References

Core Concepts

Generics and Wildcards

Java generics allow you to create classes, interfaces, and methods that operate on different types in a type - safe manner. Wildcards are a part of generics, and the ? extends wildcard is used to represent an unknown type that is a subtype of a specified type. For example, Collection<? extends Number> can hold a collection of any subtype of Number, such as Integer, Double, etc.

Type Compatibility

When dealing with Collection<? extends ...>, Java has strict rules about type compatibility. A collection of a specific type cannot be directly assigned to a collection with a wildcard type if the types are not in a proper subtype relationship.

Typical Usage Scenarios

Reading from a Collection

One of the most common use cases for Collection<? extends ...> is when you want to read elements from a collection without modifying it. For example, you might have a method that takes a collection of any subtype of Number and calculates the sum of its elements.

Working with Hierarchical Data

If you have a class hierarchy, you can use Collection<? extends ...> to work with collections of different subtypes in a unified way. For instance, if you have a Shape class with subclasses like Circle and Rectangle, you can write a method that takes a collection of any subtype of Shape and performs some operation on each shape.

Common Pitfalls

Incorrect Assignment

A common mistake is trying to assign a collection of a specific type to a collection with a wildcard type in an incorrect way. For example, trying to assign a List<Integer> to a List<? extends Double> will result in a compilation error because Integer is not a subtype of Double.

Modifying a Collection with ? extends

Another pitfall is trying to add elements to a collection declared with ? extends. Since the exact type is unknown, Java does not allow you to add elements to such a collection, except for null.

Best Practices

Use ? extends for Read - Only Operations

As mentioned earlier, use ? extends when you only need to read elements from a collection. This ensures type safety and allows you to work with collections of different subtypes.

Use ? super for Write - Only Operations

If you need to add elements to a collection, use the ? super wildcard instead. For example, Collection<? super Integer> can accept a collection of any supertype of Integer, and you can add Integer objects to it.

Code Examples

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

// Example of a method that calculates the sum of elements in a collection of any subtype of Number
public class CollectionExample {

    public static double sum(Collection<? extends Number> numbers) {
        double sum = 0;
        for (Number number : numbers) {
            sum += number.doubleValue();
        }
        return sum;
    }

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

        // This works because Integer is a subtype of Number
        double result = sum(integers);
        System.out.println("Sum: " + result);

        // Trying to add elements to a Collection<? extends ...> will result in a compilation error
        // Collection<? extends Number> numberCollection = integers;
        // numberCollection.add(4); // Compilation error
    }
}

Conclusion

The “cannot be converted to java.util.Collection<? extends …>” error is a result of incorrect type usage in Java’s generic system. By understanding the core concepts of generics and wildcards, typical usage scenarios, common pitfalls, and best practices, you can write more robust and type - safe Java code. Remember to use ? extends for read - only operations and ? super for write - only operations to avoid common mistakes.

FAQ

Q: Why can’t I add elements to a Collection<? extends ...>?

A: The ? extends wildcard represents an unknown subtype. Since Java does not know the exact type, it cannot ensure type safety when adding elements. The only element you can add is null.

Q: Can I assign a List<Number> to a List<? extends Integer>?

A: No, you cannot. Number is a supertype of Integer, not a subtype. So, a List<Number> cannot be assigned to a List<? extends Integer>.

References