У меня есть интерфейс для моделей, которые могут иметь родителей и детей
public interface HierarchyAware<T extends HierarchyAware<T>> {
List<T> getChildren();
T getParent();
void addChild(T child);
}
У меня есть служебный метод, который берет плоский список и строит дерево:
<T extends HierarchyAware<? super T>> List<T> buildTree(List<T> flatElements);
Работает нормально, поэтому нет необходимости размещать тело метода.
У меня также есть метод, который превращает дерево в простой список:
public static List<? extends HierarchyAware<?>> flattenTree(List<? extends HierarchyAware<?>> treeElements) {
List<HierarchyAware<?>> flatList = new ArrayList<HierarchyAware<?>>();
for (HierarchyAware<?> t : treeElements) {
flatList.add(t);
if (t.getChildren() != null) {
flatList.addAll(flattenTree(t.getChildren()));
}
}
return flatList;
}
но мне действительно не нравится его подпись, и я хочу сделать его более конкретным. Итак, я закодировал это так:
@SuppressWarnings("unchecked")
public static <T extends HierarchyAware<? super T>> List<T> flattenTree(List<T> treeElements) {
List<T> flatList = new ArrayList<T>();
for (T t : treeElements) {
flatList.add(t);
if (t.getChildren() != null) {
flatList.addAll((List<? extends T>) flattenTree(t.getChildren()));
}
}
return flatList;
}
Подпись идеальна для меня, но мне не нравится необходимость подавлять предупреждения. И самая большая проблема заключается в том, что компилятор Eclipse находит этот код корректным, но javac дает мне:
[javac] C:\somepath\TreeUtil.java:112: <T>flattenTree(java.util.List<T>) in somepackage.TreeUtil cannot be applied to (java.util.List<capture#687 of ? super T>)
[javac] flatList.addAll((List<? extends T>) flattenTree(t.getChildren()));
[javac] ^
Почему два компилятора ведут себя по-разному, и как мне переписать этот метод, чтобы он был без ошибок и в идеале без предупреждений?