我有一个列出自定义对象的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>
?
提前致谢!
答案 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
}