如何使用通配符在Java中复制泛型集合

时间:2015-06-16 16:14:19

标签: java generics

考虑这个java类:

import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;


public class NumberSet {

    private Collection<? extends Number> numbers;

    public NumberSet(Collection<? extends Number> numbers) {
        this.numbers = numbers;
    }

    public NumberSet(NumberSet other) {

        //copy other.numbers to this.numbers
        numbers = new LinkedList<>();
        for (Iterator<? extends Number> it = other.numbers.iterator(); it.hasNext();) {
            numbers.add(it.next()); // Here's Syntax Error near `it.next()`
        }

    }
}

for循环中存在此语法错误:

actual argument Number cannot be converted to CAP#1 by method invocation conversion
where E is a type-variable:
    E extends Object declared in interface Collection
where CAP#1 is a fresh type-variable:
    CAP#1 extends Number from capture of ? extends Number

我理解PECS的含义,但我想为此类实现一个复制构造函数。将使用复制的实例作为other的快照。任何想法?

1 个答案:

答案 0 :(得分:5)

更改:

 Collection<? extends Number> dst 

致:

 Collection<? super Number> dst

使用? extends不允许添加。有一种称为GetPut原则的东西。引自Generics and CollectionsPhilip Wadler书:

  

获取和放置原则:当你得到时使用扩展通配符   结构中的值,当你只放置时使用超级通配符   将值放入结构中,并且当两者都得到时不要使用通配符   并把

另请查看PECS以获得有关此现象的更常见解释。 (但是,我更喜欢GETPUT原则优先于ProducerConsumer原则,因为它不那么令人困惑)