1

I know that in the following method in Collection<E>:

public void addAll(Collection<? extends E> subcollection);

We use Collection<? super E> there to allow a collection that solely exists of sub-elements, example:

List<Drivable> drivables = new ArrayList<>();
List<Car> cars = new ArrayList<>();
//we need the wildcard here, because of the following line:
drivables.addAll(cars);

However, are such bounded wildcards needed in my following method?

public static <E> Collection<E> requireNonEmpty(final Collection<E> collection) throws NoSuchElementException {
    if (collection.isEmpty()) {
        throw new NoSuchElementException("collection must be non-empty");
    }
    return collection;
}

This uses a similar idiom as Objects.requireNonNull(T object), which actually returns the T object.

So, is there any benefit (or is it even wrong?) to write my method as the following?

public static <E> Collection<? super E> 
    requireNonEmpty(final Collection<? extends E> collection);
skiwi
  • 66,971
  • 31
  • 131
  • 216
  • You might want to read this - [Java Generics: What is PECS?](http://stackoverflow.com/q/2723397/738746). – Bhesh Gurung Apr 21 '14 at 14:47
  • @BheshGurung I have read that, however I seem to not be able to apply that information on my usecase here. – skiwi Apr 21 '14 at 14:47
  • You method itself is generic, so you could pass collection of any type to it. Imagine if the type parameter `E` was declared at the class level and your method as an instance method, and you wanted to method to take a collection of E or any subclass/superclass of E then you would need to use it. – Bhesh Gurung Apr 21 '14 at 14:48
  • For whatever you are doing in your method, I don't see why you would want to use bounds. – Bhesh Gurung Apr 21 '14 at 14:54
  • 2
    Note that the `requireNonEmpty` return type is losing information, unlike `requireNonNull`. For example, one could pass in a `Set` and only get a `Collection` back. To remedy this, it should be declared as `public static > C requireNonEmpty(final C collection)`. – Paul Bellora Apr 21 '14 at 15:56
  • Paul Bellora should extend that comment into an answer, because it is correct. On such a function, there is no need to lose type information. – Ross Judson Apr 21 '14 at 16:07

1 Answers1

2

The use of Collection<? extends E> subcollection makes the passed parameter a universal donor - i.e. it can be read from with freedom.

You do not need to read objects from the passed collection so you do not need any wildcards.

Incidentally using Collection<? super E> subcollection makes it a universal recipient - i.e. you can add to it.

See When to use extends and super for a clear introduction.

Also a good answer covering this Generic lower unbound vs upper bounded wildcards.

Community
  • 1
  • 1
OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213