Общий тип возврата не работает - PullRequest
2 голосов
/ 22 января 2012

Я иду через пример.

public interface Visitor<T> {
    public void visit(T e);
}

class Sum<T extends Integer> implements Visitor<T> {

    private int sum = 0;



    @Override
        public void visit(T element) {
            sum += element;
        }

        public T value() {
            return sum;
        }

}

В возвращаемой сумме оператора return value T) () указывается, что несоответствие типов: невозможно преобразовать из int в T. Почему это так и как устранить проблему.

Ответы [ 4 ]

3 голосов
/ 22 января 2012

В вашем случае есть две проблемы:

  1. T extends Integer не совсем корректно, поскольку Integer не может быть расширено, то есть это класс final. Поэтому вы можете смело менять объявление класса на

    class Sum implements Visitor<Integer> { ...
    
  2. Во-вторых, метод T value() не является частью интерфейса и поэтому не должен (не должен) иметь тип T. Вы можете смело заменить его на public int value() или public Integer value().

Поэтому полученный код будет выглядеть так:

class Sum implements Visitor<Integer> {
    private int sum = 0;

    @Override
    public void visit(Integer element) {
        sum += element.intValue();
    }

    public int value() {
        return sum;
    }
}
1 голос
/ 22 января 2012

Вы можете использовать метод intValue в классе Integer (фактически унаследованном от Number), т.е.

sum += element.intValue();

Причина, по которой вы не можете просто использовать sum += element, заключается в том, чтоКомпилятор не знает, что такое конкретный класс T, поэтому он не может выполнить автоматическую коробку.T может быть Integer, но вы объявили T как T extends Integer, поэтому компилятор не знает, что на самом деле подкласс T.

Теперьв вашем случае это становится немного интереснее, потому что Integer - последний класс.Вы можете утверждать, что компилятор должен быть в состоянии выяснить, что T всегда будет Integer.Очевидно, он этого не делает.

Возможно, это тот случай, когда вы не хотите использовать дженерики: никогда не может быть подкласса Integer, так почему бы не избавиться от обобщенияв целом?

class Sum implements Visitor<Integer> {
    public void visit(Integer i) {
        sum += i;
    }
}

Это должно работать очень хорошо.

1 голос
/ 22 января 2012

В реализации Generics всегда используйте Wrapper классы вместо primitive типов данных. например Для int вы должны использовать Integer аналогично для double, float, long и т. Д. Доступны классы-обёртки Double, Float и Long соответственно.

1 голос
/ 22 января 2012

Это потому, что int является примитивным типом в Java, а Integer является классом.Проблема в том, что вы не можете напрямую назначить int на Integer.Решение может состоять в том, чтобы изменить return sum; на return (T) sum;.

...