Проблема с ДЖЕНЕРИКАМИ

178
28 января 2019, 06:30

Помогите мучает воппрос, есть абстрактный класс с одним абстрактным методом:

public abstract class AbstractDTO {
    private long id;
    public abstract  <T extends AbstractEntity> void convertListToDTO(List<T> entityList);
}

Есть наследник, где Client наследуется от AbstractEntity:

public class ClientDTO extends AbstractDTO{
    public void convertListToDTO(List<Client> clients) {
    }
}

Но такая запись выдает ошибку:

both methods have same erasure

Исправляю на такую запись

public abstract class AbstractDTO <T extends AbstractEntity> {
    private long id;
     abstract void convertListToDTO(List<T> entityList);
}

И у наследника:

public class ClientDTO extends AbstractDTO<Client>{
    public void convertListToDTO(List<Client> clients) {
    }

Так работает. В чем причина?

Answer 1

В первом варианте вы объявляете абстрактный генерик метод, а во втором - абстрактный генерик класс. Объявление генерик метода в наследнике, в первом варианте, должно быть таким:

    @Override
    public <T extends AbstractEntity> void convertListToDTO(List<T> entityList) {
       // какой-то код
    }

Такое объявление ограничивает T внутри типа аргумента List<T> entityList. То есть, если у вас есть классы:

class Client extends AbstractEntity {
}
class Client2 extends Client {
}
class Client3 {
}

то T может быть Client или Client2, но не Client3:

    ClientDTO dto = new ClientDTO();
    List<Client> list = new ArrayList<>();
    dto.convertListToDTO(list);

компилируется

    ClientDTO dto = new ClientDTO();
    List<Client2> list = new ArrayList<>();
    dto.convertListToDTO(list);

компилируется

    ClientDTO dto = new ClientDTO();
    List<Client3> list = new ArrayList<>();
    dto.convertListToDTO(list);

не компилируется

Ваша же попытка объявить метод public void convertListToDTO(List<Client> clients) воспринимается как попытка объявить другой метод. Но поскольку генериков в рантайме нет, то оба метода получат одну и ту же сигнатуру convertListToDTO(List), на что компилятор и ругается.

READ ALSO
Методы jsp страницы, переопределение init()

Методы jsp страницы, переопределение init()

Страница jsp компилируется в сервлетУ нее есть методы jspInit(), jspService(HttpServletRequest, HttpServletResponse), jspDestroy()

194
Как изменять ImageView из другого класса?

Как изменять ImageView из другого класса?

Есть MainActivityjava с activity_main

153