Как исправить "Выражение типа List требует непроверенного преобразования..."?

В фрагменте Java:

SyndFeedInput fr = new SyndFeedInput();
SyndFeed sf = fr.build(new XmlReader(myInputStream));
List<SyndEntry> entries = sf.getEntries();

последняя строка генерирует предупреждение

"Выражение типа List требует необработанного преобразования для соответствия List<SyndEntry>"

Какой подходящий способ исправить это?

Ответ 1

Так как getEntries возвращает raw List, он может содержать что угодно.

Подходом без предупреждения является создание нового List<SyndEntry>, а затем добавление каждого элемента результата sf.getEntries() в SyndEntry перед добавлением его в ваш новый список. Collections.checkedList не выполняет эту проверку для вас, хотя было бы возможно реализовать ее для этого.

Выполняя свою личную настройку, вы "соблюдаете условия гарантии" генериков Java: если a ClassCastException поднят, он будет связан с литой в исходном коде, а не с невидимым вставкой компилятором.

Ответ 2

Это обычная проблема при работе с API до Java 5. Чтобы автоматизировать решение от erickson, вы можете создать следующий общий метод:

public static <T> List<T> castList(Class<? extends T> clazz, Collection<?> c) {
    List<T> r = new ArrayList<T>(c.size());
    for(Object o: c)
      r.add(clazz.cast(o));
    return r;
}

Это позволяет:

List<SyndEntry> entries = castList(SyndEntry.class, sf.getEntries());

Поскольку это решение проверяет, что элементы действительно имеют правильный тип элемента с помощью приведения, он безопасен и не требует SuppressWarnings.

Ответ 3

Похоже, что SyndFeed не использует generics.

У вас может быть небезопасный бросок и предупреждение:

@SuppressWarnings("unchecked")
List<SyndEntry> entries = (List<SyndEntry>) sf.getEntries();

или вызовите Collections.checkedList - хотя вам все равно нужно подавить предупреждение:

@SuppressWarnings("unchecked")
List<SyndEntry> entries = Collections.checkedList(sf.getEntries(), SyndEntry.class);

Ответ 4

Вы пишете SyndFeed?

Возвращает ли sf.getEntries список или List<SyndEntry>? Я предполагаю, что он возвращает List и его изменение в return List<SyndEntry> устранит проблему.

Если SyndFeed является частью библиотеки, я не думаю, что вы можете удалить предупреждение без добавления аннотации @SuppressWarning("unchecked") к вашему методу.

Ответ 5

Если вы используете Guava, и все, что вы хотите сделать, это перебрать ваши значения:

for(SyndEntry entry: Iterables.filter(sf.getEntries(), SyndEntry.class){
  ...
}

Если вам нужен фактический список, вы можете использовать

List<SyndEntry> list = Lists.newArrayList(
    Iterables.filter(sf.getEntries(), SyndEntry.class));

или

List<SyndEntry> list = ImmutableList.copyOf(
    Iterables.filter(sf.getEntries(), SyndEntry.class));

Ответ 6

Если вы посмотрите на javadoc для класса SyndFeed (я думаю, вы ссылаетесь на класс com.sun.syndication.feed.synd.SyndFeed), метод getEntries() не возвращает java.util.List<SyndEntry>, а возвращает только java.util.List.

Для этого вам нужен явный прилив.

Ответ 7

Если вы не хотите ставить @SuppressWarning ( "unchecked" ) на каждый вызов sf.getEntries(), вы всегда можете сделать оболочку, которая вернет List.

Смотрите этот другой вопрос

Ответ 8

Еще проще

return new ArrayList<?>(getResultOfHibernateCallback(...))

Ответ 9

SyndFeedInput fr = new SyndFeedInput();
SyndFeed sf = fr.build(new XmlReader(myInputStream));
List<?> entries = sf.getEntries();