类型安全:未选中从对象转换为列表<MyObject>

Elo*_*rro 19 android listview casting filter custom-object

我有一个列出自定义对象的ListView(比方说MyObject).

我想通过动态过滤它,EditText所以我不得不getFilter()用publishResults方法实现一个:

@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
    MyObjectAdapter.this.setItems((List<MyObject>) results.values);
    MyObjectAdapter.this.notifyDataSetChanged();
}
Run Code Online (Sandbox Code Playgroud)

此时,Eclipse抱怨道: Type safety: Unchecked cast from Object to List<MyObject>

我确信这个演员总是真实的,但Eclipse只建议添加,@SuppressWarnings("unchecked")但我完全反对,SuppressWarnings因为它只是隐藏问题,而不是解决方案......

我尝试添加:

if(results.values instanceof List<MyObject>)
Run Code Online (Sandbox Code Playgroud)

但Eclipse再次抱怨,这没有解决任何问题......

Cannot perform instanceof check against parameterized type List<MyObject>. Use the form List<?>

我知道转换将始终是正确的,但这是使代码确定results.values实际上是正确的方法List<MyObject>吗?

提前致谢!

Med*_*o42 20

如果所有必须工作的是a Object,那么你不能在运行时检查你实际上有一个List<MyObject>,因为泛型类型MyObject仅用于编译时类型检查,它在运行时不可用.这就是您尝试添加instanceof检查时出错的原因.

如果你确定你Object真的总是List<MyObject>那么我会说@SuppressWarnings没关系,如果你记录为什么你确定它不是问题.

如果你绝对想要避免警告,你可以创建自己的List实现(比方说MyObjectList),这本身并不是通用的,而是实现的List<MyObject>.然后你可以在运行时进行instanceof检查MyObjectList.

另一个选择是检查并转换List<?>instanceof错误建议.然后,您可以迭代列表中的元素并检查它们是否实际上是MyObject的所有实例,并将它们复制到新的List<MyObject>.


Elo*_*rro 15

好吧,我终于找到了解决方案.

正如@ Medo42所说:

另一种选择是检查并转换为List,因为错误建议的实例.然后你可以遍历该列表中的元素,并检查他们实际上是为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);
}
Run Code Online (Sandbox Code Playgroud)

谢谢大家的帮助!


lok*_*oko 13

尝试这样的事情:

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

filteredItems = tempList; // <-- set filtered
Run Code Online (Sandbox Code Playgroud)