1

我正在阅读 Java 教程,偶然发现了一些我不理解的东西。在 Collections 线索中,他们谈论Wrapper 实现,我注意到两个静态工厂方法 -

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

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

我想知道为什么同步包装器不使用有界通配符?ie 为什么synchronizedCollection的签名不是如下?

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

2 回答 2

2

Collection<? extends T> c这样你只能得到东西但不能添加到它,这在 的情况下是有意义的unmodifiableCollection,对于方法,参数应该只充当生产者。但是在 的情况下synchronizedCollection,它是同步的但仍然是修改的,它也应该能够添加和删除,所以它必须是Collection<T> c,它应该充当生产者和消费者。

这可能有助于了解什么是 PECS(生产者扩展消费者超级)?

于 2012-10-03T19:31:55.490 回答
-1

我认为unmodifiableCollection是错误的。两种方法都打算包装Collection<T>Collection<T>,没有理由更改类型参数。

当然,接受 a 更灵活Collection<? extends T>,因此调用者可以请求将 a 转换Collection<Integer>为不可修改的Collection<Integer>or Collection<Number>orCollection<Object>等​​。但是谁需要呢?只读Collection<Integer>在各方面​​都比Collection<Number>无论如何都要好。

如果输入类型本身包含通配符,例如

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

unmodifiableCollection(Collection<? extends T>)我们可以做

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

unmodifiableCollection2(Collection<T>)我们必须

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

第二个版本更混乱,但它可能在政治上更正确。

于 2012-10-03T19:55:46.627 回答