2011-09-07 10 views
42

El siguiente código:no puede llevar a cabo instanceof comprobar contra ArrayList tipo parametrizado <Foo>

((tempVar instanceof ArrayList<Foo>) ? tempVar : null); 

causas:

no puede llevar a cabo instanceof cheque contra parametrizado tipo ArrayList<Foo>. Utilice el formulario ArrayList<?> vez desde más información de tipo genérico se borrará en tiempo de ejecución

Puede alguien explicar qué se entiende por "información más genérica tipo serán borrados en tiempo de ejecución" y cómo solucionar este problema?

+1

Google: "escriba java borrado" – jjnguy

Respuesta

45

Significa que si tiene algo que está parametrizado, p. List<Foo> fooList = new ArrayList<Foo>();, la información de Generics se borrará en el tiempo de ejecución. En cambio, esto es lo que la JVM verá List fooList = new ArrayList();.

Esto se llama type erasure. La JVM no tiene información de tipo parametrizada de List (en el ejemplo) durante el tiempo de ejecución.

¿Una solución? Como la JVM no tiene información del tipo Parametrizado en el tiempo de ejecución, no hay forma de que pueda hacer un instanceof de ArrayList<Foo>. Puede "almacenar" el tipo parametrizado explícitamente y hacer una comparación allí.

10

Debido a borrado de tipo, el tipo parametrizado de ArrayList no se conocerá en tiempo de ejecución. Lo mejor que puede hacer con instanceof es verificar si tempVar es un ArrayList (de cualquier cosa). Para hacer esto de manera genérica, use:

((tempVar instanceof ArrayList<?>) ? tempVar : null); 
1

No puede arreglar eso. La información de tipo para Generics no está disponible en tiempo de ejecución y no tendrá acceso a ella. Solo puedes verificar el contenido de la matriz.

1

instancia del operador funciona en tiempo de ejecución. Pero java no lleva la información del tipo parametrizado en tiempo de ejecución. Se borran en el momento de la compilación. De ahí el error.

23

Siempre se puede hacer esto en vez

try 
{ 
    if(obj instanceof ArrayList<?>) 
    { 
     if(((ArrayList<?>)obj).get(0) instanceof MyObject) 
     { 
      // do stuff 
     } 
    } 
} 
catch(NullPointerException e) 
{ 
    e.printStackTrace(); 
} 
+7

¿qué pasa si está vacío –

+0

@RafaelRuiz creo que un simple molde try/catch para el tipo ArrayList haría el truco? –

0

siempre se puede hacer esto

Crear una clase

public class ListFoo { 
    private List<Foo> theList; 

    public ListFoo(List<Foo> theList { 
    this.theList = theLista; 
    } 

    public List<Foo> getList() { 
    return theList; 
    } 
} 

no es lo mismo pero ...

myList = new ArrayList<Foo>; 
..... 
Object tempVar = new ListFoo(myList); 
.... 
((tempVar instanceof ListFoo) ? tempVar.getList() : null); 
2

Esto es suficiente:

if(obj instanceof ArrayList<?>) 
{ 
    if(((ArrayList<?>)obj).get(0) instanceof MyObject) 
    { 
     // do stuff 
    } 
} 

De hecho, instanceof comprueba si el operando de la izquierda es null o no y devuelve false si es realmente null.
Entonces: no es necesario atrapar NullPointerException.

+2

¿No sería más adecuado para un comentario en la publicación original? – Greg

0

Puede utilizar

boolean isInstanceArrayList = tempVar.getClass() == ArrayList.class 
Cuestiones relacionadas