Javaスニペットの場合:
SyndFeedInput fr = new SyndFeedInput();
SyndFeed sf = fr.build(new XmlReader(myInputStream));
List<SyndEntry> entries = sf.getEntries();
最後の行は警告を生成します
「型の式はList
、準拠するためにチェックされていない変換が必要ですList<SyndEntry>
」
これを修正する適切な方法は何ですか?
Javaスニペットの場合:
SyndFeedInput fr = new SyndFeedInput();
SyndFeed sf = fr.build(new XmlReader(myInputStream));
List<SyndEntry> entries = sf.getEntries();
最後の行は警告を生成します
「型の式はList
、準拠するためにチェックされていない変換が必要ですList<SyndEntry>
」
これを修正する適切な方法は何ですか?
これは、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
。
getEntries
raw を返すため、List
何でも保持できます。
警告なしのアプローチは、新しい を作成し、結果List<SyndEntry>
の各要素を にキャストしてから、新しいリストに追加することです。はこのチェックを行いませんが、そうするように実装することは可能でした。sf.getEntries()
SyndEntry
Collections.checkedList
事前に独自のキャストを行うことで、Java ジェネリックの「保証条件に準拠」します。aClassCastException
が発生した場合、コンパイラによって挿入された目に見えないキャストではなく、ソース コード内のキャストに関連付けられます。
SyndFeed
ジェネリックを使用していないようです。
安全でないキャストと警告の抑制のいずれかを行うことができます。
@SuppressWarnings("unchecked")
List<SyndEntry> entries = (List<SyndEntry>) sf.getEntries();
またはCollections.checkedListを呼び出します- ただし、警告を抑制する必要があります。
@SuppressWarnings("unchecked")
List<SyndEntry> entries = Collections.checkedList(sf.getEntries(), SyndEntry.class);
書きましたSyndFeed
か?
sf.getEntries
リストを返しますList<SyndEntry>
か?私の推測では、それは戻りList
、returnに変更するとList<SyndEntry>
問題が解決します。
がライブラリの一部である場合、メソッドにアノテーションをSyndFeed
追加せずに警告を削除することはできないと思います。@SuppressWarning("unchecked")
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));
クラスのjavadocを見るとSyndFeed
(クラスを参照していると思いますcom.sun.syndication.feed.synd.SyndFeed
)、メソッドgetEntries()はを返しませんjava.util.List<SyndEntry>
が、を返しますjava.util.List
。
したがって、これには明示的なキャストが必要です。
各 sf.getEntries() 呼び出しに @SuppressWarning("unchecked") を配置したくない場合は、List を返すラッパーをいつでも作成できます。
この他の質問を参照してください
さらに簡単
return new ArrayList<?>(getResultOfHibernateCallback(...))
Bruno De Fraine の答えは素晴らしいです。ただし、入力引数 "Collection<?> c" のサイズが 0 の場合、ルーチンは null ポインターでクラッシュします。これを回避するためにマイナーな改善を提案します (そして HashSet のバージョンを示します):
public static <T> HashSet<T> castHashSet(Class<? extends T> clazz, Collection<?> c) {
int cSize = (c == null) ? 0 : c.size();
HashSet<T> hashSet = new HashSet<T>(cSize);
if (c != null) {
for (Object o : c)
hashSet.add(clazz.cast(o));
}
return hashSet;
}