カスタムオブジェクトをリストするListViewがあります(MyObject
としましょう)。
EditText
を使用して動的にフィルタリングしたいので、publishResultsメソッドを使用してgetFilter()
を実装する必要がありました。
_@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
MyObjectAdapter.this.setItems((List<MyObject>) results.values);
MyObjectAdapter.this.notifyDataSetChanged();
}
_
この時点で、Eclipseは不平を言います:_Type safety: Unchecked cast from Object to List<MyObject>
_
このキャストは常に正しいと確信していますが、Eclipseは@SuppressWarnings("unchecked")
の追加のみを提案していますが、SuppressWarnings
は完全に反対です。
追加してみました:
_if(results.values instanceof List<MyObject>)
_
しかし、Eclipseは再び文句を言い、これは何も解決しません...
_Cannot perform instanceof check against parameterized type List<MyObject>. Use the form List<?>
_
キャストは常に正しいことはわかっていますが、_results.values
_が実際に_List<MyObject>
_であることを確認するための適切な方法はどれですか。
前もって感謝します!
さて、私は最終的に解決策を見つけることができました。
@ Medo42が言ったように:
別のオプションは、instanceofエラーが示すように、チェックしてリストにキャストすることです。次に、リスト内の要素を反復処理し、それらが実際にMyObjectのすべてのインスタンスであるかどうかを確認して、新しいリストにコピーできます。
この特定のケースを「警告なし」で機能させるために、まったく新しいオブジェクトを作成するプロセスはしていませんが、これは正しい方向でした。
@lokokoのアイデアを取り入れ、新しいsetItems()
メソッドで使用しました。List<MyObject>
ではなくObject
パラメータを使用して、
結果コードは次のとおりです。
public void setItems(List<MyObject> var){
this.list = var;
}
public void setItems(Object var){
List<MyObject> result = new ArrayList<MyObject>();
if (var instanceof List){
for(int i = 0; i < ((List<?>)var).size(); i++){
Object item = ((List<?>) var).get(i);
if(item instanceof MyObject){
result.add((MyObject) item);
}
}
}
setItems(result);
}
皆さんの助けに感謝します!
作業する必要があるのがObject
だけの場合、ジェネリック型MyObject
はコンパイルにのみ使用されるため、実際にList<MyObject>
があることを実行時に確認することはできません。 -型チェック時not実行時に利用可能これが、instanceof
チェックを追加しようとするとエラーになる理由です。
Object
が本当にList<MyObject>
であることが確かな場合は、問題がないと確信できる理由を文書化すれば、@SuppressWarnings
は大丈夫だと思います。
警告を絶対に避けたい場合は、独自のList
実装(たとえば、MyObjectList
)を作成し、それ自体は汎用的ではなくList<MyObject>
を実装します。次に、実行時にinstanceof
に対してMyObjectList
チェックを実行できます。
もう1つのオプションは、instanceof
エラーが示すように、List<?>
を確認してキャストすることです。次に、リストの要素を繰り返し処理して、それらが実際にMyObjectのすべてのインスタンスであるかどうかを確認し、それらを新しいList<MyObject>
にコピーします。
このようなものを試してください:
List<?> result = (List<?>) results.values;
for (Object object : result) {
if (object instanceof MyObject) {
tempList.add((MyObject) object); // <-- add to temp
}
}
filteredItems = tempList; // <-- set filtered
setItems()
に渡す前にチェックを実行できます。
_final Object myListObj = reuslts.values;
if(myListObj instanceof List<?>) {
if(((List<?>)myListObj).get(0) instanceof MyObject)
// You can safely suppress the warning here because you made sure it is a List containing MyObject
MyObjectAdapter.this.setItems((List<? extends MyObject>) myListObj);
}
_
ただし、それに応じてsetItems()
メソッドを変更する必要があります。
_public void setItems(List<? extends MyObject> list) {
// Your code here
}
_