Типизация объектов

121
07 февраля 2021, 11:20

У меня есть класс AppealTemlate, который содержит список сущностей extends AbstractField. Выглядит это примерно так:

public class AppealTemplate extends AbstractEntity {
    private List<AbstractField> fields = new ArrayList<>();
}

Реализаций AbstractField несколько, около полудюжины. Когда на маппер приходит AppealTemplate, маппер не знает, какие именно сущности лежат в списке, поэтому на первое время я сделал такую реализацию маппинга fields в DTO:

source.getFields()
                    .forEach(f -> {
                        if (f.getFieldType().equals(FieldType.CHECKBOX)) {
                            destination.getFields().add(checkBoxFieldMapper.toDto((CheckBoxField) f));
                        } else if (f.getFieldType().equals(FieldType.DATE_PICKER)) {
                            ...
}

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

private Map<String, EntityDtoMapper<? extends AbstractField, ? extends AbstractFieldDto>> fillMappers() {
    mappers = new HashMap<>();
    mappers.put(FieldType.DATE_PICKER.getName(), datePickerFieldMapper);
    mappers.put(FieldType.CHECKBOX.getName(), checkBoxFieldMapper);
    ...
}

Далее, я пытаюсь сделать следующее:

source.getFields()
                .forEach(f -> {
                    destination.getFields().add(mappers.get(f.getFieldType().getName()).toDto((AbstractField) f));

Но часть кода ((AbstractField) f) подчёркивает красным и пишет, что toDto() не может быть применено к AbstractField, потому что оно ожидает capture<? extends AbstractField>.

Я уже задавал подобный вопрос здесь и мне здорово помог пользователь @defaultlocale Но в этот раз почему-то этот рецепт не работает, хотя, сущности те же и всё то же.

UPD: уточняющая информация:

private Map<String, EntityDtoMapper<? extends AbstractField, ? extends AbstractFieldDto>> mappers;

toDto():

@Override
public D toDto(E entity) {    //E extends AbstractEntity, D extends AbstractDto
    return Objects.isNull(entity)
            ? null
            : mapper.map(entity, dtoClass);    //private Class<D> dtoClass;
}

В разложенном на переменные виде интересующая часть кода выглядит так:

fields
         .forEach(f -> {
            List<AbstractFieldDto> destinationFields = destination.getFields();
            EntityDtoMapper<? extends AbstractField, ? extends AbstractFieldDto> entityDtoMapper
                    = mappers.get(f.getFieldType().getName());
            AbstractField abstractField = f;
            AbstractFieldDto abstractFieldDto = entityDtoMapper.toDto(abstractField);
            destinationFields.add(abstractFieldDto);
READ ALSO
Как удалить все строки в текстовом файле, начинающиеся с определенного символа?

Как удалить все строки в текстовом файле, начинающиеся с определенного символа?

Как удалить все строки в текстовом файле, начинающиеся с определенного символа?

135
Ошибка загрузки рекламы AdMob в плагине для phonegap/cordova

Ошибка загрузки рекламы AdMob в плагине для phonegap/cordova

Я пишу мобильное приложение используя phonegapДля монетизации я решил использовать плагин cordova-plugin-admobpro

118
Как удалить объект из массива по индексу внутри объекта по клику на данный объект?

Как удалить объект из массива по индексу внутри объекта по клику на данный объект?

Всем доброго времени сутокОчень сильно прошу мне помочь и сильно не бить

112