У меня проблема с универсальной системой Java.
В моей программе есть обертка для списков, которая должна иметь метод для возврата своего внутреннего списка:
public class Wrapper<T, S extends List<T>> {
private S list;
public Wrapper(S list) {
this.list = list;
}
public S get() {
return list;
}
}
Затем есть Контекст, который содержит Карту с различными Обертками и метод, который возвращает список оберток, связанных с идентификатором:
public class Context {
private Map<String, Wrapper> map;
public Wrappers() {
map.put("a", new Wrapper(ArrayList<String>());
map.put("b", new Wrapper(LinkedList<Integer>());
}
public <T, S extends List<T>> S getList(String id) {
return map.get(id).get();
}
}
Теперь, когда я вызываю getList (), я хочу получить предупреждение компилятора или, по крайней мере, способ реализовать ошибку до того, как будет выдано исключение ClassCastException.
public class Receiver {
public doSomething() {
Context c = new Context();
c.createWrappers();
// Ok
ArrayList<String> list1 = c.getList("a");
LinkedList<Integer> list2 = c.getList("b");
// Compiler error or some way do check in getList().
ArrayList<Integer> list3 = c.getList("a");
LinkedList<String> list4 = c.getList("b");
}
}
На самом деле я пробовал много вещей, таких как изменение определения Wrapper:
public class Wrapper<T, S extends List>
Но когда я хочу реализовать функцию get (), я сталкиваюсь с проблемой, я могу либо определить функцию следующим образом:
public List<T> get() {
return list;
}
или как это
public S get() {
return list;
}
В первом примере это все еще возможно сделать.
public doSomething() {
//...
LinkedList<String> list = c.getList("a");
}
и во втором примере это можно будет сделать.
public doSomething() {
//...
ArrayList<Integer> list = c.getList("a");
}
Есть ли способ определить метод get таким образом?
public S<T> get() {
return list;
}
Мне кажется, что нет способа проверить одновременно и тип списка, и тип элементов.