我的编译器是JDK 6.0_65,以下是我的代码(Deque.java):
import java.util.Iterator;
public class Deque<Item> implements Iterable<Item> {
private Node first;
private Node last;
private class Node {
Item value;
Node next;
}
public Deque(){} // construct an empty deque
public Iterator<Item> iterator() {
// return an iterator over items in order from front to end
return new DequeIterator<Item>();
}
private class DequeIterator<Item> implements Iterator<Item> {
private Node current = first;
public boolean hasNext() {
return current.next != null;
}
public Item next() {
Item item = current.value;
current = current.next;
return item;
}
public void remove() {}
}
public static void main(String[] args) {
// unit testing
Deque<Integer> dq = new Deque<Integer>();
}
}
在外部范围内:
public class Deque<Item> implements Iterable<Item> {
被使用。
在内在范围内:
private class DequeIterator<Item> implements Iterator<Item> {
被使用。
在DequeIterator
的范围内。我希望local-scope(内部类范围)Item
将从Item
隐藏类范围Deque<Item>
。
但是,在编译阶段,javac
会抛出这样的错误:
Deque.java:2: error: incompatible types
Item item = current.value;
^
required: Item#2
found: Item#1
where Item#1,Item#2 are type-variables:
Item#1 extends Object declared in class Deque
Item#2 extends Object declared in class Deque.DequeIterator
它说Item#2
和Item#1
是不兼容的类型,这对我来说很混乱,因为我已使用Item
将类型参数DequeIterator
传递到new DequeIterator<Item>()
。
有没有人对此有任何想法?
答案 0 :(得分:7)
我希望本地范围(内部范围)
中的类范围项Item
会影响Deque<Item>
这基本上就是发生的事情 - 内部范围Item
遮蔽了外部范围。您已将外部Item
传递给构造函数并不重要。内部类有编译问题,因为你试图将一个外部类型Item
的值赋给一个内部类型的变量 - Item
。
要解决此问题,只需使嵌套类非通用:
private class DequeIterator implements Iterator<Item>
通过这种方式,您将使用外部 - Item
而不声明您不需要的另一个Item
类型参数。
答案 1 :(得分:3)
是内部类通用Item
阴影通用的封闭类Item
,这正是编译器抱怨的原因。你写了Item item=current.value
(这就是问题所在)。这里Item
引用内部类的泛型类型,但current.value
是封闭类的泛型类型Item
。这些类型不同!编译器将它们命名为Item#1
和Item#2
。您只需从内部类DequeIterator
中删除通用性:
public class Deque<Item> implements Iterable<Item> {
private static class DequeIterator implements Iterator<Item> {
}
}
答案 2 :(得分:1)
无法保证Item#1
和Item#2
总是相同。您可以将此类方法添加到Deque
:
public Iterator<Integer> boom() {
return new DequeIterator<Integer>();
}
这显然没有任何意义,但是因为迭代器类的Item
与封闭类“Item
s无关(因为内部Item
类型参数阴影外部)它是完全合法的。
你没有理由给DequeIterator类一个类型参数,你可以简单地声明它:
private class DequeIterator implements Iterator<Item> {
// Content remains unchanged
}
答案 3 :(得分:0)
试试这个,你甚至可以删除<T>
:
private class DequeIterator<T> implements Iterator<Item> {
...
}
我认为问题是某种阴影问题,其中内部和外部Item
被认为是不同的。