【发布时间】:2019-04-20 21:41:16
【问题描述】:
我正在尝试找到正确的泛型和通配符排列来完成这项工作。类型已更改,所有其他代码已删除,以使其尽可能简单。
这里我有一个泛型类,其上限为Number,它实现了Iterable。它包含一个泛型类型的List。
我想传入任何Number 子类的List,并从List 字段返回该类型的Iterator。
这是显然行不通的基本想法。
class GenericQuestion<T extends Number> implements Iterable<T> {
List<T> numbers;
GenericQuestion(List<T> number) {
this.numbers = number;
}
public Iterator<T> iterator() {
return numbers.iterator();
}
static void main() {
for (Number n : new GenericQuestion<Number>(new ArrayList<Integer>())) { // <---- error
System.out.println(n.byteValue());
}
}
}
这给出了预期的错误
incompatible types: ArrayList<Integer> cannot be converted to List<Number>
上限通配符来拯救!差不多……
class GenericQuestion<T extends Number> implements Iterable<T> {
List<? extends T> numbers;
GenericQuestion(List<? extends T> number) {
this.numbers = number;
}
public Iterator<T> iterator() {
return numbers.iterator(); // <----- error
}
static void main() {
for (Number n : new GenericQuestion<Number>(new ArrayList<Integer>())) {
System.out.println(n.byteValue());
}
}
}
现在我对迭代器类型冲突感到困惑。
incompatible types: Iterator<CAP#1> cannot be converted to Iterator<T>
where T is a type-variable:
T extends Number declared in class GenericQuestion
where CAP#1 is a fresh type-variable:
CAP#1 extends T from capture of ? extends T
现在从逻辑上讲,我很确定将返回的迭代器强制转换为类型 (Iterator<T>) 是完全安全的,
但我宁愿以“正确”的方式做到这一点。我已经尝试了各种各样的事情。这是另一个绝望的尝试,但仍然没有成功。
class GenericQuestion<T extends Number> implements Iterable<T> {
List<T> numbers;
<U extends Number> GenericQuestion(List<U> number) {
this.numbers = number; // <----- error
}
public Iterator<T> iterator() {
return numbers.iterator();
}
static void main() {
for (Number n : new GenericQuestion<Number>(new ArrayList<Integer>())) {
System.out.println(n.byteValue());
}
}
}
错误。
incompatible types: List<U> cannot be converted to List<T>
where U,T are type-variables:
U extends Number declared in constructor <U>GenericQuestion(List<U>)
T extends Number declared in class GenericQuestion
我认为也许辅助函数可以弥补差距,但我的尝试没有任何运气。
这似乎不应该那么难。强制施法真的可行吗?或者是否有一个通用声明可以让这一切一起工作?
【问题讨论】: