Какова проблема с этим кодом Java, имеющим дело с Дженериками?

interface Addable<E> {
    public E add(E x);
    public E sub(E y);
    public E zero();
}

class SumSet<E extends Addable> implements Set<E> {

    private E element;

    public SumSet(E element) {
        this.element = element;
    }

    public E getSum() {
        return element.add(element.zero());
    }
}

Это кажется этим element.add() не возвращается E extends Addable а скорее Object. Почему это? Это имеет что-нибудь, чтобы сделать с Java, не зная во времени выполнения, каковы типы объектов действительно, таким образом, это просто предполагает, что они Объекты (таким образом требующий броска)?

Спасибо

5
задан devoured elysium 17 April 2010 в 03:40
поделиться

4 ответа

Это должно быть:

class SumSet<E extends Addable<E>> implements Set<E> {

Ваш исходный код указывает, что каждый элемент SumSet должен быть экземпляром E, класса, который реализует Addable (что эквивалентно Addable ). Изменяя Addable на Addable , вы указываете, что методы add, sub и zero класса E должны принимать и возвращать экземпляры E (а не просто Object) .

Обратите внимание, что переменная типа E в SumSet не имеет ничего общего с указанной выше переменной E. Итак:

class SumSet<T extends Addable<T>> implements Set<T> {

    private T element;

    public SumSet(T element) {
        this.element = element;
    }

    public T getSum() {
        return element.add(element.zero());
    }
}

тоже работает нормально.

5
ответ дан 18 December 2019 в 09:48
поделиться

Вам нужно сказать > , а не .

Это связано с тем, что при использовании необработанного типа все ссылки на его (несуществующие) параметры типа стираются.

3
ответ дан 18 December 2019 в 09:48
поделиться

Вместо того, чтобы создавать класс SumSet , реализующий Set , вы можете подумать, сможете ли вы получить то, что вам нужно, написав метод, который может суммировать все элементы в установленный.

public static <T extends Addable<T> > T sum(Set<T> set)
{
    T sum = null;
    for (T t : set)
    {
        if (sum == null)
        {
            sum = t;
        }
        else
        {
            sum = sum.add(t);
        }
    }
    return sum;
}
0
ответ дан 18 December 2019 в 09:48
поделиться

Попробуйте:

class SumSet<E extends Addable<E>> implements Set<E> {

Я не знаю, именно это вы имеете в виду, но в основном проблема в том, что вы используете Addable в объявлении SumSet как необработанный тип. Это удаляет все общие типы параметров и заставляет Addable отображаться в SumSet как:

interface Addable {
  Object add(Object x);
  Object sub(Object y);
  Object zero();
}

Очевидно Object не является E , следовательно Ошибка. См. Что такое необработанный тип? в FAQ по Java Generics.

Кстати, public не нужен для методов в определениях интерфейсов.

9
ответ дан 18 December 2019 в 09:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: