我正在阅读Java教程并偶然发现了一些我不理解的内容。在Collections路径中,他们谈到Wrapper implementations,我注意到两个静态工厂方法 -
public static <T> Collection<T> synchronizedCollection(Collection<T> c);
public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c);
我想知道为什么同步包装器不使用有界通配符?一世。即为什么synchronizedCollection的签名不是以下内容?
public static <T> Collection<T> synchronizedCollection(Collection<? extends T> c);
答案 0 :(得分:2)
Collection<? extends T> c
,你只能得到东西但不能添加它,这在unmodifiableCollection
的情况下是有意义的,对于该方法,参数应该只作为生产者。但是在synchronizedCollection
的情况下,它是同步的但仍然是modifialbe,它也应该能够添加和删除,因此它必须是Collection<T> c
,它应该充当生产者和消费者。
答案 1 :(得分:-1)
我认为unmodifiableCollection
是错误的。两种方法都打算将Collection<T>
包装为Collection<T>
,没有理由更改类型参数。
确保接听Collection<? extends T>
更灵活,因此来电者可以请求将Collection<Integer>
转换为不可修改的Collection<Integer>
或Collection<Number>
或Collection<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);
第二个版本更加混乱,但它可能在政治上更正确。