type property open debugger android listview casting filter custom-object

android - property - Escriba seguridad: no verificada conversión de objeto a lista<MyObject>



open graph facebook (4)

Tengo un ListView que lista un objeto personalizado (digamos MyObject ).

Quiero filtrarlo dinámicamente a través de un EditText así que tuve que implementar un getFilter() con un método publishResults:

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

En este punto, Eclipse se queja: Type safety: Unchecked cast from Object to List<MyObject>

Estoy seguro de que este reparto siempre será verdadero, pero Eclipse solo sugiere agregar @SuppressWarnings("unchecked") pero estoy totalmente en contra de SuppressWarnings porque solo esconde el problema, no una solución ...

Intenté agregar:

if(results.values instanceof List<MyObject>)

Pero Eclipse se queja de nuevo, y esto no resuelve nada ...

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

Sé que el casting siempre será correcto, pero ¿cuál es la forma correcta de hacer que el código se asegure de que results.values sea ​​realmente una List<MyObject> ?

¡Gracias por adelantado!


Bueno, finalmente logré encontrar una solución.

Así como @ Medo42 dijo:

Otra opción es verificar y enviar a la Lista como lo sugiere el error de ejemplo. Luego puede iterar sobre los elementos de la lista y verificar si son realmente todas las instancias de MyObject, y copiarlas en una nueva Lista.

A pesar de que no pasé por el proceso de crear un objeto completamente nuevo para hacer que este caso en particular funcionara "sin advertencias", esta fue la dirección correcta.

Así que tomé la idea de @lokoko y la uso en un nuevo método setItems() , con un parámetro Object lugar de una List<MyObject> para asegurarme

El código de resultado es el siguiente:

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

¡Gracias a todos por su ayuda!


Intenta algo como esto:

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


Puede realizar la comprobación antes de pasarla a 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); }

Sin embargo, necesita cambiar su método setItems() consecuencia:

public void setItems(List<? extends MyObject> list) { // Your code here }


Si todo lo que tiene para trabajar es un Object , entonces no puede verificar en tiempo de ejecución que realmente tiene una List<MyObject> , porque el tipo genérico MyObject solo se usa para la verificación de tipos en tiempo de compilación, no está disponible en tiempo de ejecución . Es por eso que recibe un error cuando intenta agregar la instanceof verificación.

Si está seguro de que su Object realmente es siempre una List<MyObject> entonces diría que @SuppressWarnings está bien, si documenta por qué está seguro de que no es un problema.

Sin embargo, si absolutamente desea evitar una advertencia, puede crear su propia implementación de la List (por ejemplo, MyObjectList ) que no es en sí misma genérica pero implementa la List<MyObject> . Luego, puede realizar una instanceof comprobación contra MyObjectList en tiempo de ejecución.

Otra opción es verificar y emitir a la List<?> Como sugiere el error instanceof . Luego puede iterar sobre los elementos en la lista y verificar si son realmente todas las instancias de MyObject, y copiarlas en una nueva List<MyObject> .