【发布时间】:2018-01-10 08:06:43
【问题描述】:
我正在尝试创建一个子类 Iterable 的类。这类似于question。但是,我需要让列表中的对象成为特定类的子类,例如下面我的示例中的 QObject。另外,我需要我的迭代器实现ListIterator接口相关的具体方法。
问题是我实现 ListIterator 接口的内部类在我的实现中没有“返回”基本泛型类型 QObject。我做 QueueListIterator 泛型的方式有问题。
现在,如果我在示例代码中使用 Queue
那么,我的问题是为什么会发生这种情况,有没有办法指定 QueueListIterator 来识别基本泛型类型?
public class Queue<T extends QObject> implements Iterable<T> {
/**
* The list of items in the queue.
*/
protected List<T> myList;
// other methods and defs
public final Iterator<T> iterator() {
return (new QueueListIterator());
}
public final ListIterator<T> listIterator() {
return (new QueueListIterator());
}
private class QueueListIterator implements ListIterator<T> {
protected ListIterator<T> myIterator;
protected QueueListIterator() {
myIterator = myList.listIterator();
}
@Override
public void add(T o) {
throw new UnsupportedOperationException("The method add() is not supported for Queue iteration");
}
@Override
public boolean hasNext() {
return myIterator.hasNext();
}
@Override
public boolean hasPrevious() {
return myIterator.hasPrevious();
}
@Override
public T next() {
return myIterator.next();
}
@Override
public int nextIndex() {
return myIterator.nextIndex();
}
@Override
public T previous() {
return myIterator.previous();
}
@Override
public int previousIndex() {
return myIterator.previousIndex();
}
@Override
public void remove() {
throw new UnsupportedOperationException("The method remove() is not supported for Queue iteration");
}
@Override
public void set(T o) {
throw new UnsupportedOperationException("The method set() is not supported for Queue iteration");
}
}
}
// testing code
public static void test(){
Queue q = new Queue();
// put some stuff in the Queue
QObject r1 = new QObject(q.getTime(), "A");
q.enqueue(r1);
QObject r2 = new QObject(q.getTime(), "B");
q.enqueue(r2);
// Does not work!
// incompatible object types, Object cannot be converted to QObject in the for( : ) construct
for (QObject qo : q) {
System.out.println(qo);
}
}
【问题讨论】:
-
我编辑了这个问题,因为我的第一篇文章错过了 LT 和 GT 标志。是的, Queue
q 确实提供了必要的类型信息。但是,我相信如果我对获取 QObjects 没问题,我不应该在声明队列时提供基本泛型类型 -
这只是你使用泛型的一个问题。应该是
Queue<QObject> q = new Queue<QObject>()。 -
我了解 Queue
的工作原理。但是,如果我只是将队列声明为 Queue q = new Queue(),那么我的其他方法(未显示)例如 T removeFirst() 将获得通用基类型 QObject 而不会从声明中提供,因为他们知道类型 T 必须是 QObject 的子类型。但是,我无法让 Iteratable 做同样的事情。 -
是的。根本没有办法让它发挥作用。但是你不应该担心它,因为无论如何你都不应该在没有类型参数的情况下使用
Queue。 -
路易斯,我现在同意。我现在必须更多地研究泛型类型系统。