Есть класс
public abstract class Converter<Data extends SensorData, Entity extends DbEntity & Persistable>
определяю в нем статический метод
public static <Data extends SensorData, Entity extends Persistable & DbEntity> Converter<Data, Entity> get(Class<Entity> cls)
из которого пытаюсь возвращать не абстрактных детей класса Converter в зависимости от переданного класса. Компилятор ругается, что не может допустить такого.
И с другой стороны у меня в Observable есть .map, которая преобразует список
List<T extends Persistable & DbEntity>
, который мне как раз хотелось бы передать в конвертер. Тут компилятор так же подчеркивает красным, независимо от того использую ли я wildcard или T. Можете помочь разобраться, почему такое поведение и как это можно обойти?
Конкретный пример:
Есть сущности, которые я достаю из репозитория, для каждой сущности определяется метод, вроде этого
@Override
public <T> Single<List<ShortSummaryData>> getShortSummaries(LogicalCondition<? extends Expression<T>, ?> expression) {
return DataStorage.getDatabase()
.select(ShortSummaryEntity.class)
.where(expression)
.get().observableResult()
.compose(RxCompose.listOrEmpty())
.map(ShortSummaryConverter.get()::toApiPayloadList)
.firstOrError();
}
единственное, что в этих методах различается это класс, которые передается в select и метод map который должен обрабатывать результат выборки из бд, в зависимости от типа возвращаемых данных. В голову сразу приходит желания избавится от десятка однообразных методов и использовать дженерики. Для каждого класса есть конвертер, который умеет из сущностей бд (генерятся аннотейшн процессором Requery) делать сущности для серверного апи и наоборот. Конвертеры я тоже сделал на дженериках, есть абстрактный родитель, типизированный классами бд-сущностей и апи-сущностей. То есть каждый из его детей несет одну и ту же функциональность
public abstract class Converter<Data extends SensorData, Entity extends DbEntity & Persistable> {
public List<Data> toApiPayloadList(List<Entity> list) {
List<Data> data = new ArrayList<>();
for (Entity entity : list) {
data.add(toApiPayload(entity));
}
return data;
}
public abstract Entity toDbEntity(Data data);
public abstract Data toApiPayload(Entity entity);
public Entity toSyncedDbEntity(Data data) {
Entity entity = toDbEntity(data);
entity.setSynced(true);
return entity;
}
public List<Entity> toSyncedDbList(List<Data> data) {
List<Entity> list = new ArrayList<>();
for (Data d : data) {
list.add(toSyncedDbEntity(d));
}
return list;
}
public List<Entity> toDbList(List<Data> data) {
List<Entity> list = new ArrayList<>();
for (Data d : data) {
list.add(toDbEntity(d));
}
return list;
}
public List<Data> responseToData(LoadResponse<Data> loadResponse) {
if (Utils.isEmpty(loadResponse.getDataGroups())) {
return new ArrayList<>();
} else {
List<Data> list = new ArrayList<>();
for (DataGroup<Data> dg : loadResponse.getDataGroups()) {
List<Data> contains = dg.getItems();
for (Data d : contains) {
d.setSensorId(dg.getSensorId());
}
list.addAll(contains);
}
return list;
}
}
}
Задачу с тем, чтобы обощить класс передаваемый в select я решил, но теперь нужно сделать так, чтобы возвращался типизированный конвертер и преобразобвывал дженерик список дб сущностей в дженерик список апи-сущностей.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
ЗдравствуйтеНадо нужно написать бота для чат-приложения
Делаю Android приложениеКакое, не особо важно