25

カスタムオブジェクトをリストする ListView があります (たとえばMyObject)。

を介して動的にフィルタリングしたいので、 publishResults メソッドでEditTextを実装する必要がありました。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>どれですか?

前もって感謝します!

4

4 に答える 4

23

から作業する必要があるのが だけの場合、ジェネリック型はコンパイル時の型チェックにのみ使用され、実行時に使用できないため、Object実際に があることを実行時に確認できませ。これが、チェックを追加しようとするとエラーが発生する理由です。List<MyObject>MyObjectinstanceof

Object本当に常に a であると確信している場合は、それが問題ではないと確信している理由を文書化すれば、問題ないと思いますList<MyObject>@SuppressWarnings

ただし、警告を絶対に回避したい場合は、それ自体は一般的ではなく、 を実装する独自のList実装 (たとえば) を作成できます。次に、実行時にチェックを行うことができます。MyObjectListList<MyObject>instanceofMyObjectList

List<?>別のオプションは、instanceofエラーが示唆するようにチェックしてキャストすることです。次に、リスト内の要素を反復処理し、それらが実際にすべて MyObject のインスタンスであるかどうかを確認し、それらを new にコピーできますList<MyObject>

于 2013-02-01T09:38:20.647 に答える
16

さて、私はついに解決策を見つけることができました。

@ Medo42が言ったように:

別のオプションは、instanceofエラーが示唆するように、リストをチェックしてキャストすることです。次に、リスト内の要素を反復処理して、それらが実際にすべてMyObjectのインスタンスであるかどうかを確認し、それらを新しいリストにコピーできます。

この特定のケースを「警告なし」で機能させるためにまったく新しいオブジェクトを作成するプロセスを経ていませんが、これは正しい方向でした。

そこで、@ lokokoのアイデアを採用し、それを新しいsetItems()メソッドで使用します。確実にするためにObject、aの代わりにパラメーターを使用します。List<MyObject>

結果のコードは次のとおりです。

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);
}

皆さんの助けに感謝します!

于 2013-02-01T11:45:11.783 に答える
15

このようなことを試してください:

List<?> result = (List<?>) results.values;
for (Object object : result) {
    if (object instanceof MyObject) {
        tempList.add((MyObject) object); // <-- add to temp
    }
}

filteredItems = tempList; // <-- set filtered
于 2013-02-01T10:34:13.677 に答える
3

に渡す前にチェックを実行できます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
}
于 2013-02-01T09:37:07.120 に答える