如何使Java Iterable从扩展泛型返回基子类型
我试图使一个类的子类是可测试的。这与此类似。但是,我需要让列表中的对象是特定类的子类,例如下面示例中的QObject。此外,我需要迭代器来实现与ListIterator接口相关的特定方法 问题是实现ListIterator接口的内部类在实现中没有返回基泛型类型QObject。我使用QueueListIterator泛型的方式有问题 现在,如果我在我的示例代码中用Queue声明队列,它就会工作。这必须提供允许迭代器获得正确类型所需的信息。但是,即使基泛型类型是QObject,并且队列类中的其他方法使用基泛型类型,但仅将其声明为Queue并不会这样做 所以,我的问题是为什么会发生这种情况,有没有办法指定QueueListIterator来识别基本泛型类型如何使Java Iterable从扩展泛型返回基子类型,java,generics,iteration,Java,Generics,Iteration,我试图使一个类的子类是可测试的。这与此类似。但是,我需要让列表中的对象是特定类的子类,例如下面示例中的QObject。此外,我需要迭代器来实现与ListIterator接口相关的特定方法 问题是实现ListIterator接口的内部类在实现中没有返回基泛型类型QObject。我使用QueueListIterator泛型的方式有问题 现在,如果我在我的示例代码中用Queue声明队列,它就会工作。这必须提供允许迭代器获得正确类型所需的信息。但是,即使基泛型类型是QObject,并且队列类中的其他方法
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);
}
}
如果您这样声明q会怎么样: 队列
也见
这是一个评论,而不是答案。我认为这是一个评论,而不是答案。我原来的帖子已经指出了这一点。我编辑了这个问题,因为我的第一篇帖子遗漏了LT和GT标志。是的,队列q提供了必要的类型信息。但是,我相信,如果我对获取QObject没有意见,那么在声明队列时就不必提供基本泛型类型。这只是泛型使用中的一个问题。应该是Queue q=new Queue。我知道队列可以工作。但是,如果我只是将队列声明为queue q=new queue,那么未显示的其他方法(如T removeFirst)将获得通用基类型QObject,而不从声明中提供它,因为它们知道类型T必须是QObject的子类型。但是,我不能得到迭代的方法来做同样的事情。根本没有办法做到这一点。但您不必担心,因为您无论如何都不应该使用没有类型参数的队列。Louis,我现在同意了。我现在必须进一步研究泛型类型系统。这是有帮助的,尽管令人失望。似乎有理由让我的内部类以我想要的方式知道基泛型类型。然而,理解不应该使用原始类型表明了我对类型系统的基本误解。现在清楚一点了。