2010-11-10 24 views
23

Todo el asunto de los genéricos me está dando un vuelco, y más aún el RTT.Java isInstance vs instanceOf operator

¿Qué es Specificis? Ah, bueno aquí está el quid:

enum QueryHelper { 
    query1, 
    query2; 
    static <T> QueryHelper getQueryHelper (Class<T> expectedReturn) { 
    if (expectedReturn.isInstance (SomeRelatedClass.class)) 
     return query1; 
    else 
     return query2; 
    } 
} 

y luego lo llamaría así:

... 
QueryHelper helper = QueryHelper.getQueryHelper(SomeRelatedClass.class); 
... 

Esto es por lo que yo puedo asignar de forma flexible el tipo de retorno consulta en el ayudante real. Hace algo de fundición y creación de objetos. Lo que estoy viendo es que no hay coincidencia, ¿debería estar haciendo esto de otra manera? ¿O toda la idea es mala?

Y el verdadero corazón de esto es que no entiendo la diferencia entre class.isInstance y el operador instanceOf? ¿Debo usar el último?

Respuesta

29

Este es para poder asignar de manera flexible el tipo de retorno de consulta en el asistente real.

No hay nada flexibles sobre el tipo de retorno de este método

static <T> QueryHelper getQueryHelper (Class<T> expectedReturn) { 
    if (expectedReturn.isInstance (SomeRelatedClass.class)) 
     return query1; 
    else 
     return query2; 
} 

siempre devolverá una instancia de QueryHelper. Si desea que el tipo de retorno para ser flexibles que se necesita para definirlo como algo así como:

static <T> T getQueryHelper (Class<T> expectedReturn) { 
} 

Ahora el tipo de retorno es flexible, ya que dependerá del tipo del argumento

Y el verdadero corazón de esto es que no entiendo la diferencia entre class.isInstance y el operador instanceOf?

La diferencia es que instanceof hace un tipo a comprobar que se fija en tiempo de compilación, por ejemplo:

static boolean isInstance(Object myVar) { 
    return (myVar instanceof Foo); 
} 

siempre comprobar que myVar es una instancia de Foo, mientras que

static <T> boolean isInstance(Object myVar, Class<T> expectedType) { 
    return expectedType.isInstance(myVar); 
} 

comprobará que myVar es una instancia de expectedType, pero expectedType puede ser un tipo diferente cada vez que se llame al método

+0

Su uso ex suficiente para isState es hacia atrás. Sería expectedType.isInstance (myVar); – Affe

+0

Gracias por aclarar eso - definitivamente necesitaba reducir la velocidad y pensar cuando estaba escribiendo este código. Desde entonces ha cambiado de forma, para ser realmente útil. ¡Gracias de nuevo! – rybit

1

El argumento esperado de isInstance es un objeto que puede ser una instancia de la clase que representa su objeto de clase. Lo que está comparando es una instancia de la clase ... java.lang.Class! Entonces no va a coincidir.

por ejemplo, sería cierto:

Class.class.isInstance(SomeRelatedClass.class); 

también sería cierto (sin comentarios arquitectónico sobre la cordura de su ayudante en realidad la construcción de consultas de esta manera)

expectedReturn.isInstance(new SomeRelatedClass()); 
3

Class.isInstance() doesn No funciona como espera tu código. Comprueba si el objeto que le pasas es una instancia de la clase. En su código:

expectedReturn.isInstance(SomeRelatedClass.class) 

El objeto que está pasando es un objeto Clase. Prueba este lugar, que devuelve verdadero:

Class.class.isInstance(SomeRelatedClass.class); 

Lo que probablemente está buscando es Class.isAssignableFrom(), por ejemplo:

Object.class.isAssignableFrom(Class.class); 

significa que usted puede hacer esto:

Class klass = ...; 
Object o = klass;