"목록 유형의 표현식에 확인되지 않은 변환이 필요합니다 ..."는 어떻게 수정합니까?


137

자바 스 니펫에서 :

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

마지막 줄은 경고를 생성합니다

"유형의 표현 List에 적합하도록 선택하지 않은 변환이 필요합니다 List<SyndEntry>"

이 문제를 해결하는 적절한 방법은 무엇입니까?

답변:


96

getEntriesraw를 반환 하므로 List아무 것도 보유 할 수 있습니다.

경고없는 접근 방식은 새로운 List<SyndEntry>을 만든 다음 새로운 목록에 추가 sf.getEntries()하기 SyndEntry전에 결과 의 각 요소를 캐스트 하는 것입니다. 이 검사는 사용자를 위해 수행 Collections.checkedList하지는 않지만 구현하는 것이 가능할 수도 있습니다.

자체 캐스트를 수행하면 Java 제네릭의 "보증 조건을 준수하는 것"입니다. a ClassCastException가 발생하면 컴파일러가 삽입 한 보이지 않는 캐스트가 아니라 소스 코드의 캐스트와 연관됩니다.


9
고마워-컴파일러에 의해 수행 된 "보증"과 보이지 않는 캐스트와 내 코드에서 명시 적으로 캐스트 된 캐스트에 대한 흥미로운 통찰력.
user46277

1
예, 통일되지 않은 제네릭의 가치는 다소 제한적이지만 그것이 제공하는 것 중 하나입니다. 명확히하기 위해서는 코드가 유형 안전 경고없이 컴파일되어야합니다.
erickson

안녕하세요 erickson, 이것이 실제로 최선의 해결책이라는 데 동의합니다. 이 솔루션의 일반 버전은 내 답변 stackoverflow.com/questions/367626/… 을 확인하십시오 .
Bruno De Fraine

115

Java 5 이전 API를 처리 할 때 발생하는 일반적인 문제입니다. 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.


5
Bruno가 제안한 방법과 관련하여 많은 요소가있는 목록을 가질 때 응용 프로그램 성능이 저하되지 않습니까? 자바는 그들 각각을 캐스팅해야 할 것이다.
will824

2
보장을 원한다면 비용이 듭니다. 다른 저렴한 옵션이 있습니까? 호출 된 원시 콜렉션 리턴 메소드를 제어하거나 지연 호출 방식을 사용하여 메소드를 호출하거나 콜렉션에 액세스하는 경우도 있습니다. 메소드 호출 후 전체 콜렉션을 고려하는 것이 있습니까?
dan

28

SyndFeed제네릭을 사용하지 않는 것 같습니다 .

안전하지 않은 캐스팅과 경고 억제가있을 수 있습니다.

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

또는 Collections.checkedList를 호출하십시오. 그래도 경고를 표시하지 않아도됩니다.

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

둘 다 경고를 억제하기 때문에 서로에게 유리한 점이 있습니까? 감사! 또한 : 점검되지 않은 억제가 시행 된 경우 캐스트가 필요합니까?
Dan Rosenstark

3
@Yar : 음, Collections.checkedListSyndEntry 이외의 요소를 나중에 추가하지 못하게합니다. 나는 개인적으로 checkedList많이 사용 하지 않지만 어쨌든 종종이 확인되지 않은 캐스트 상황에 빠지지 않습니다 ...
Jon Skeet

9

당신은 작성 했습니까 SyndFeed?

sf.getEntriesList 또는 List<SyndEntry>?를 반환 합니까 ? 내 추측은 그것이 돌아 List오고 그것을 돌려 주기로 바꾸면 List<SyndEntry>문제가 해결된다는 것입니다.

SyndFeed라이브러리의 일부인 경우 @SuppressWarning("unchecked")메소드에 주석을 추가하지 않고 경고를 제거 할 수 없다고 생각합니다 .


명시 적 캐스트를 추가 할 수도 있습니다.
Uri

3
코드는 형식이 안전하지 않기 때문에 캐스트는 다른 경고를 생성합니다.
erickson

SyndFeedrometools.github.io/rome/ROMEReleases/ROME1.0Release.html 에서 제공됩니다 . 문제는 사람들이에서 발견처럼 로마의 최신 버전에서 수정 될 것으로 보인다 mvnrepository.com/artifact/com.rometools/rome/1.9.0
daloonik

2

구아바를 사용하고 있고 원하는 것은 값을 반복하는 것입니다.

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
SyndFeedInput fr = new SyndFeedInput();
SyndFeed sf = fr.build(new XmlReader(myInputStream));
List<?> entries = sf.getEntries();

2
여기에 제공된 코드로 문제를 해결하더라도 그 이유를 간단히 설명해 보시기 바랍니다. 게시 된 답변으로 문제가 해결되는 이유를 설명하십시오.
sbrattla

1

클래스의 javadoc을 보면 (클래스 SyndFeed를 참조한다고 생각합니다 com.sun.syndication.feed.synd.SyndFeed) getEntries () 메소드는 반환하지 않지만 java.util.List<SyndEntry>just 만 반환합니다 java.util.List.

따라서 명시 적으로 캐스팅해야합니다.


0

각 sf.getEntries () 호출에 @SuppressWarning ( "unchecked")을 넣지 않으려면 항상 List를 반환하는 래퍼를 만들 수 있습니다.

참조 이 다른 질문을


0

훨씬 쉬움

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


그런 다음 ArrayList <?>의 각 요소에 대해 사용 시간에 적절한 캐스팅 (재 캐스팅?)을 처리합니다.
ingyhere
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.