Как мне исправить «Выражение типа List нуждается в непроверенном преобразовании ...»? - PullRequest
127 голосов
/ 15 декабря 2008

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

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

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

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

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

Ответы [ 9 ]

111 голосов
/ 17 мая 2010

Это распространенная проблема при работе с 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.

94 голосов
/ 15 декабря 2008

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

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

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

25 голосов
/ 15 декабря 2008

Похоже, SyndFeed не использует дженерики.

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

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

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

@SuppressWarnings("unchecked")
List<SyndEntry> entries = Collections.checkedList(sf.getEntries(), SyndEntry.class);
7 голосов
/ 15 декабря 2008

Вы написали SyndFeed?

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

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

2 голосов
/ 18 декабря 2014

Если вы используете 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));
1 голос
/ 08 мая 2015
SyndFeedInput fr = new SyndFeedInput();
SyndFeed sf = fr.build(new XmlReader(myInputStream));
List<?> entries = sf.getEntries();
1 голос
/ 15 декабря 2008

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

Так что для этого вам нужно явное приведение.

0 голосов
/ 16 мая 2011

Еще проще

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

0 голосов
/ 16 декабря 2008

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...