Что значит (Список ) в приведение из списка «универсальных» объектов, представленных интерфейсом к конкретному типу, реализующему его? - PullRequest
0 голосов
/ 19 марта 2020

Я работаю над приложением Java и у меня есть следующие сомнения относительно правильного способа преобразования списка объектов, реализующих интерфейс , в конкретный c конкретный объект. У меня есть следующий код, он работает нормально, но я не до конца понимаю смысл синтаксиса:

List<ExcelTabInterface> compVibrAndTempDTOListOriginal =  excelService.getCompVibrAndTempTab();

List<CompVibrAndTempDTO> compVibrAndTempDTOList = (List<CompVibrAndTempDTO>)(List<?>) compVibrAndTempDTOListOriginal;

Как вы можете видеть в первой строке, я вызываю метод для получения списка объектов, реализующих интерфейс с именем ExcelTabInterface . Таким образом, этот список содержит любой объект, реализующий мой ExcelTabInterface интерфейс.

Затем мне нужно преобразовать этот список в список конкретных объектов, реализующих мой интерфейс, я сделал это со второй строкой. Я преобразую свой исходный список в список CompVibrAndTempDTO (это класс, реализующий мой ExcelTabInterface ).

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

List<CompVibrAndTempDTO> compVibrAndTempDTOList = (List<CompVibrAndTempDTO>) compVibrAndTempDTOListOriginal;

но я не уверен, что он не может работать и что правильный путь:

List<CompVibrAndTempDTO> compVibrAndTempDTOList = (List<CompVibrAndTempDTO>)(List<?>) compVibrAndTempDTOListOriginal;

Почему? Что именно означает это (Список) ? Зачем мне это нужно, чтобы бросить в Список ?

1 Ответ

1 голос
/ 19 марта 2020

Проблема в том, что дженерики инвариантны, вот длинное объяснение .

Так что написание этого, например:

List<ExcelTabInterface> compVibrAndTempDTOListOriginal = new ArrayList<>();
List<CompVibrAndTempDTO> compVibrAndTempDTOList = compVibrAndTempDTOListOriginal;

не будет работать.

Но если вы сначала присваиваете «супертипу» или «родителю всех обобщенных c списков» (у меня нет лучшего имени), а затем сужаетесь до типа, компилятор должен доверять вы (через предупреждение), потому что это может произойти, чтобы быть правдой:

    List<ExcelTabInterface> compVibrAndTempDTOListOriginal = new ArrayList<>();
    List<?> parentOfAll = compVibrAndTempDTOListOriginal;

    // a warning here
    List<CompVibrAndTempDTO> compVibrAndTempDTOList = (List<CompVibrAndTempDTO>) parentOfAll;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...