Java Generics, не может конвертировать из E в E

Мой код не может преобразовать из E в E. Я могу сделать приведение к типу E, но на данном этапе он кажется излишним. Мой массив уже объявлен как E-type.

import java.util.Iterator;

public class DataTypeDemo<E>
{
private E[] data = (E[]) new Object [10];

public MyIterator newIterator()
{
    return new MyIterator();
}

private class MyIterator<E> implements Iterator<E>
{
    private int location;

    public boolean hasNext()
    {
        return location < data.length;
    }

    public E next()
    {
        return (data[location++]); // error here
    }

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

Компилятор, выдает эту ошибку:

DataTypeDemo.java:23: несовместимые типы найдено: E требуется: E

Ответ 1

В вашем внутреннем типе вводится его собственная переменная типа:

private class MyIterator<E /* this is the problem*/> implements Iterator<E>

И тем самым перезаписывает переменную типа внешнего класса

Измените объявление своего типа на это:

private class MyIterator implements Iterator<E>

Справка:

Ответ 2

Корень вашей проблемы - это ваш внутренний класс. Для компилятора нет гарантий того, что два E одного типа.

import java.util.Iterator;
import java.util.ArrayList;


    public class DataTypeDemo<E> 
    {
        private ArrayList<E> data = new ArrayList<E>(10);

        private class MyIterator implements Iterator<E> 
        {
            private int location;

            public boolean hasNext()
            {
                return location < data.size();
            }

            public E next()
            {
                return data.get(location++);
            }

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

Хотя как только вы осознаете проблему, не стесняйтесь реализовать свое собственное решение;)
Счастливый взлом.

Ответ 3

Это потому, что вы указали внутреннему классу MyIterator свой собственный параметр типа E. Обратите внимание, что E - это другой параметр типа, чем E охватывающего класса (вы назвали их как E, но они представляют собой два разных типа параметров).

Просто оставьте параметр типа для внутреннего класса:

private class MyIterator implements Iterator<E> {

Ответ 4

Я думаю, что проблема в том, что ваш вложенный тип итератора определяется как общий класс, также параметризованный над несвязанным типом с именем E. Чтобы исправить это, измените

private class MyIterator<E> implements Iterator<E>

Для

private class MyIterator implements Iterator<E>

В этом первом объявлении говорится, что итератор для вашего типа может быть параметризован по любому типу, а не только по типу внешнего контейнера. Он также вводит новую переменную типа E, которая отделена от E во внешней декларации. В этом втором определении говорится, что для любого типа контейнера существует один тип итератора, который не является общим по отношению к внешнему типу. Вероятно, это то, что вы намеревались.