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

时间:2013-02-01 09:16:12

标签: android listview casting filter custom-object

我有一个列出自定义对象的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>

提前致谢!

4 个答案:

答案 0 :(得分:18)

如果您需要处理的只是Object,那么您无法在运行时检查您确实拥有List<MyObject>,因为通用类型MyObject仅用于编译时类型检查,运行时可用。这就是您尝试添加instanceof支票时出错的原因。

如果您确定Object确实始终是List<MyObject>,那么我会说@SuppressWarnings没问题,如果您记录为什么您确定这不是问题。

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

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

答案 1 :(得分:11)

尝试这样的事情:

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

filteredItems = tempList; // <-- set filtered

答案 2 :(得分:11)

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

正如@ Medo42所说:

  

另一种选择是检查并转换为List作为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);
}

感谢大家的帮助!

答案 3 :(得分: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
}