Это неприятная проблема, потому что вы знаете (из семантики выражения XPath), что все элементы в списке будут экземплярами Element
, но нет никакого способа сообщить об этом компилятору Java. Если бы разработчики DOM4J подумали немного более тщательно, они бы объявили результат как List<? extends Node>
, что дало бы вам немного больше гибкости (хотя приведение все равно дало бы вам предупреждения компилятора). Это также разочаровывает, потому что причина этого правила заключается в опасности добавления неподходящих элементов в список, и что вам действительно нужно, так это неизменный список, в котором проблема не должна возникать (хотя это все же происходит, потому что генерики не обрабатывают неизменные коллекции специально).
Чистое решение, предоставленное @MagnusLutz, удовлетворит компилятор, но это дорого - оно требует копирования списка.
В Saxon 9.9 я разработал новый API, который пытается хорошо играть с дженериками, и он работает с DOM4J, так что попробуйте. Это также позволяет избежать затрат на компиляцию / интерпретацию выражения XPath для таких простых случаев, как этот. Но (к сожалению) это не решает основные ограничения обобщенных типов, особенно в отношении таких конструкций, как выражения XPath, где информация о типе, доступная для компилятора XPath, не может быть передана компилятору Java.
Что вы на самом деле хотите сделать с элементами? Если бы мне нужно было передать список методу, который требует List<Element>
, я бы, вероятно, использовал решение из @MagnusLutz. Если бы я просто хотел обработать элементы, я бы сделал
for (Node n : doc.selectNodes("//contact")) {
Element e = (Element)n;
...
}