类型安全:未选中从对象转换为列表(Type safety: Unchecked cast from

2019-07-19 02:37发布

我有一个ListView列出了自定义对象(假设MyObject )。

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

@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>

提前致谢!

Answer 1:

如果你必须从工作是一个Object ,那么你就不能在运行时检查你确实有一个List<MyObject> ,因为泛型类型MyObject仅用于编译时类型检查,它不是在运行时可用。 这就是为什么当您尝试添加得到一个错误instanceof检查。

如果你确定你的Object确实是总是一个List<MyObject>那我想说的@SuppressWarnings是OK,如果你说明为什么你肯定是没有问题的。

如果你绝对要避免的警告不过,你可以创建自己的List实现(比如, MyObjectList )本身不是通用的,但实现List<MyObject> 。 然后,你可以做一个instanceof对检查MyObjectList在运行时。

另一种选择是检查并转换为List<?>作为instanceof错误提示。 然后,你可以通过在列表中的元素进行迭代,并检查它们是否实际上是为MyObject的所有实例,并将其复制到一个新List<MyObject>



Answer 2:

好了,我终于找到一个解决方案。

正如@ Medo42说:

另一种选择是检查并转换为列表作为的instanceof错误提示。 然后你可以遍历该列表中的元素,并检查他们实际上是为MyObject的所有实例,并将其复制到一个新的列表。

虽然我没有通过,以便使这种特殊情况下的工作创造了一个全新的对象的过程中去“警告少”,这是走正确的方向。

所以我把@lokoko的理念和新的使用setItems()方法,用一个Object参数而不是一个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);
}

谢谢大家对你的帮助!



Answer 3:

尝试是这样的:

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

filteredItems = tempList; // <-- set filtered


Answer 4:

你可以把它传递给前执行检查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
}


文章来源: Type safety: Unchecked cast from Object to List