У меня есть List
, который использует подстановочный знак следующим образом:
List<DataLink<? extends Context>> dataLinks = new ArrayList<>();
dataLinks.add(new ContextDataLink());
dataLinks.add(new SomeOtherContextDataLink());
Я хочу иметь возможность перебирать этот List
и вызывать метод retrieve
для каждого элемента:
Context context = new SomeOtherContext();
for(DataLink<? extends Context> dataLink : dataLinks) {
System.out.println(dataLink.retrieve(context));
}
Однако в операторе println
я получаю следующую ошибку компилятора:
Метод retrieve(capture#3-of ? extends Context)
в типе >DataLink<capture#3-of ? extends Context>
не применим для аргументов> (Context)
Есть ли способ достичь вышеуказанной цели? Не обязательно использовать дженерики, но я чувствую, что использование дженериков позволило бы мне предотвратить явное приведение
Я прошел некоторые ответы на SO и понимаю, почему возникает эта ошибка. Однако я не могу найти решение, чтобы решить его. Я понимаю, что могу написать метод для захвата подстановочного знака, но, похоже, это тоже не решает проблему:
public static <T extends Context> void retrieve(List<DataLink<T>>
dataLinks,T context) {
for(DataLink<T> dataLink : dataLinks) {
dataLink.retrieve(context);
}
}
Когда я вызываю вышеуказанный метод получения, я получаю следующую ошибку компиляции:
Метод retrieve(List<DataLink<T>>, T)
в типе MyClass> не> применим для аргументов> (List<DataLink<? extends Context>>, Context)
Ниже приводится определение Context
, SomeOtherContext
, DataLink
реализации:
static class Context {
public String doContextThings() {
return "contextThings";
}
}
static class SomeOtherContext extends Context {
public String doSomeOtherContextThings() {
return "someOtherContextThings";
}
}
interface DataLink<T extends Context> {
public String retrieve(T context);
}
static class ContextDataLink implements DataLink<Context> {
@Override
public String retrieve(Context context) {
return context.doContextThings();
}
}
static class SomeOtherContextDataLink implements
DataLink<SomeOtherContext> {
@Override
public String retrieve(SomeOtherContext context) {
return context.doSomeOtherContextThings();
}
}
Примечание. Решение, которое не включает в себя дженерики, является наиболее простым решением, когда класс DataLink
модифицируется так, чтобы не принимать параметр типа и всегда принимать * 1042. * как тип параметра для метода retrieve
. Здесь подклассы приведут Context
к тому типу, который они ожидают. Тем не менее, вопрос остается прежним Это считается плохим дизайном или приемлемо литье в таких случаях?