首页 > 解决方案 > Iterator 期望 Object 的实例在实现它的类之外

问题描述

忍不住觉得标题有点含糊,抱歉。我无法更好地描述它。

我会更详细一点;我试图弄清楚如何让迭代器按照我想要的方式在它实现的类之外工作。我无法找到关于我的问题的任何信息。这是大学作业的一部分,AlphaTest.java 应该保持原样。

我有一个类,Alpha,它包含一个遵循双向链表原则的类,Bravo。Bravo 保存指向列表中上一个和下一个实例的链接。

我希望能够使用在 Alpha 类中实现的迭代器来遍历链表,这样我就可以使用这样的 for 循环轻松遍历每个实例 for(Bravo b: alphaInstance) {...}

我让它在 Alpha 类本身中按预期工作,但是一旦我在 Alpha 类之外尝试相同的操作,例如在 AlphaTest 中,它就不能按预期工作。一旦我尝试,我就会遇到以下错误:

Error:(220, 23) java: incompatible types: java.lang.Object cannot be converted to models.Bravo

它希望我将实例实例化为对象,如下所示:

for(Object o: alphaInstance) {...}

我当然可以将对象投射到 Bravo。但这不是任务的一部分。

请参阅下面的代码以查看发生了什么问题。问题可以在 中找到AlphaTest.java

Alpha.java

class Alpha<E extends Bravo> implements Iterable<Bravo> {
    Bravo head;

    public Alpha(Bravo head) {
       this.head = head;
    }

    public void example() {
       for(Bravo b: this) {
          // This works, it's succesfully recognized as an instance of Bravo.
       }
    }

    @Override
    public Iterator<Bravo> iterator() {
    return new BravoIterator(this.head);
    }

    private class BravoIterator implements Iterator<Bravo> {
       private Bravo currentBravo;

       public BravoIterator(Bravo head) {
          this.currentBravo = head;
       }

        @Override
        public boolean hasNext() {
            return this.currentBravo != null;
        }

        @Override
        public Wagon next() {
            Bravo data = this.currentBravo;
            this.currentBravo = this.currentBravo.getNextBravo();
            return data;
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }

    }
}

AlphaTest.java

{...}

    @BeforeEach
    private void setup() {
        // Assume this is a doubly linked list
        Bravo bravo = new Bravo(...);
        

        instanceOfAlpha = new Alpha(bravo);
    }

    public T1_checkImplementationOfIterableInterface() {
       for(Bravo b: instanceOfAlpha) {  // <---------------------------------------------[This is the problem]
          // This does not work, it expects an instance of Object.
       }
    }

{...}

标签: javagenericsiteratordoubly-linked-listiterable

解决方案


你错误地描述了这个错误。

发生的事情是instanceOfAlpha一个表达式,其类型最终成为Alpha- 您已经省略了对该变量的定义,但这似乎很明显,因为您也在为这个变量创建原始类型的值。Alpha将是所谓的原始类型- 具有类型参数但缺少参数的类型。

问题是,原始类型有点奇怪:一旦你使用原始类型,它的一切都是 raw,即使是没有使用任何你没有指定的泛型的东西。因此,iterator()您的原始Alpha表达式的方法返回一个 raw Iterator(您可能认为它返回一个Iterator<Bravo>,但事实并非如此)。因此,迭代它会返回基本对象。因此,你的 for 循环被打破了;for (Object b : instanceOfAlpha){}会编译;for (Bravo b : instanceOfAlpha){}惯于。

解决方法通常是,当编译器向您发出警告时,您不应该只是去¯_(ツ)_/¯ 我不知道那些意味着什么,所以我会像 3 只猴子一样,只是希望我不明白的任何事情都希望完全无关紧要。

它不是。真正的解决方法是:修复你的泛型,这样你就不会收到这些警告。

您没有粘贴足够的代码来准确地告诉您在这里需要做什么;可能 makeinstanceOfAlpha被声明为Alpha<?>. 更一般地说,你的第一个粘贴(你的 Alpha 类)看起来你只是不明白泛型是如何工作的;其中提到Bravo的大多数地方都应该使用E。泛型有点棘手;也许您只想完全退出。完全摆脱<E extends Bravo>部分,然后将其余部分保持原样,这也可以解决问题。


推荐阅读