1

I was going through the Java tutorial and stumbled on something which I did not understand. In the Collections trail, they talk about Wrapper implementations, there I notice two static factory methods -

public static <T> Collection<T> synchronizedCollection(Collection<T> c);

public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c);

I am wondering why does synchronized wrappers don't use bounded wildcards? i. e. Why is the signature of synchronizedCollection not the following?

public static <T> Collection<T> synchronizedCollection(Collection<? extends T> c);
Rohit Agarwal
  • 420
  • 1
  • 3
  • 18

2 Answers2

2

Collection<? extends T> c with that you can only get stuffs but cannot add to it, which makes sense in case of unmodifiableCollection, for the method the argument should only act as producer. But in case of synchronizedCollection, it's synchronized but still modifialbe, it should also be able to add and remove, so it has to be Collection<T> c, it should act as both producer and consumer.

This might be helpful to know about What is PECS (Producer Extends Consumer Super)?

Community
  • 1
  • 1
Bhesh Gurung
  • 50,430
  • 22
  • 93
  • 142
-1

I think unmodifiableCollection is in the wrong. Both methods intend to wrap Collection<T> as Collection<T>, there's no reason to change the type argument.

Sure it is more flexible to take in a Collection<? extends T>, so caller can request to convert a Collection<Integer> to an unmodifiable Collection<Integer> or Collection<Number> or Collection<Object> etc. But who needs that? A readonly Collection<Integer> is in every way better than Collection<Number> anyway.

If the input type itself contains wildcard, e.g.

Collection<? extends Number> someNumbers = ...;

with unmodifiableCollection(Collection<? extends T>) we can do

          Collection<Number> readonlyNumbers 
                             = unmodifiableCollection(someNumbers);
          Collection<Object> readonlyObjects 
                             = unmodifiableCollection(someNumbers);

but with unmodifiableCollection2(Collection<T>) we must

Collection<? extends Number> readonlyNumbers 
                             = unmodifiableCollection2(someNumbers);
Collection<? extends Object> readonlyObjects  
                             = unmodifiableCollection2(someNumbers);

the 2nd version is messier, but it is probably more politically correct.

irreputable
  • 44,725
  • 9
  • 65
  • 93