我有一个类,它在一组Integer
类型元素上返回一个迭代器,类签名是(我为了简洁而删除了访问修饰符):
class EvenIterator implements Iterator<Integer> { .... }
构造函数定义如下:
public EvenIterator(Set<Integer> intSet) { .... }
当我想将一组泛型传递给构造函数时,问题出现了。所以,要充实一点。我有可访问,填充HashSet<E> arbSet
。
我尝试将该集传递给构造函数;然而,编译器抱怨:
.... new EvenIterator(arbSet);
我收到了这个错误(据我所知):
构造函数GenericSet.EvenIterator(HashSet)未定义
所以,我认为是一个合乎逻辑的回答就是说,&#34;很好,我创建了一个新的整数类型的HashSet并将arbSet传递给它的addAll()方法&#34;:
.... new EvenIterator(new HashSet<Integer>().addAll(arbSet));
当然,这并没有解决问题;但是,错误会更好(更具体):
方法addAll(Collection&lt;?extends Integer&gt;),类型为AbstractCollection&lt;整数&gt;不适用于参数(HashSet&lt; E&gt;)
大!但是,如果不改变(或重载)EvenIterator
的构造函数,我该怎么办呢?有没有雄辩的方法来实现这一目标?或者,如果所有成员都是Integer
类型,它会不会像迭代通用列表并提取Integer
那样令人不愉快?
答案 0 :(得分:1)
从根本上说,你正试图做一个不安全的演员。您想要做什么可能在运行时生成ClassCastException
。由您(作为程序的开发人员)来确保这不会发生或正确处理这些异常。这就是你得到编译错误的原因。
您可以使用强制转换来避免编译错误,如下所示:
new EvenIterator((Set<Integer>) arbSet);
这会导致编译时警告,因为演员表仍然不安全。
如果你确定这个不安全的演员阵容确实不是代码中的问题,你可以添加:
@SuppressWarnings("unchecked")
到包含方法声明。
但是,从根本上说,在你真正忽略警告之前,你应该知道为什么需要这个演员。
编辑以下是我编写的代码片段,无需警告:
class EvenIterator implements Iterator<Integer> {
public EvenIterator(Set<Integer> intSet) { }
@Override
public boolean hasNext() {
return false;
}
@Override
public Integer next() {
return null;
}
@Override
public void remove() { }
@SuppressWarnings("unchecked")
public static void main(String[] args) {
HashSet<?> arbSet = null;
new EvenIterator((Set<Integer>) arbSet);
}
}
答案 1 :(得分:0)
它只需要是一个整数的HashSet,而不是任何类型的E。
HashSet<Integer> arbSet
应该被接受。
答案 2 :(得分:0)
您需要的可能是HashSet<E extends Integer>
。如果这不是一个选项,那么设计是错误的 - 它只是违背了泛型的目的。如果构造函数需要并期望Integers,那么Java将不允许您传递任意元素的集合 - 而使用addAll的变通方法同样是不可接受的。
Re:构造函数GenericSet.EvenIterator(HashSet)未定义
这是因为虽然HashSet是Set (Hash)Set<E>
的子类,但它不是Set<Integer>
的子类