Antes de mirar a través de mi estructura de datos genéricos para el índice de un valor, me gustaría ver si incluso this
se ha parametrizado una instancia del tipo .
Pero Eclipse se queja cuando hago esto:
@Override
public int indexOf(Object arg0) {
if (!(arg0 instanceof E)) {
return -1;
}
Este es el mensaje de error:
No se puede realizar una instancia de comprobación con el parámetro de tipo E. Utilice en su lugar su objeto de borrado ya que la información de tipo genérico se borrará en tiempo de ejecución
¿Cuál es la mejor manera de hacerlo?
java
generics
instanceof
typechecking
Nick Heiner
fuente
fuente
Class.isAssignableFrom
.Dos opciones para la verificación del tipo de tiempo de ejecución con genéricos:
Opción 1: corrompe a su constructor
Supongamos que está anulando indexOf (...), y desea verificar el tipo solo para el rendimiento, para ahorrarse iterando toda la colección.
Haz un constructor sucio como este:
Luego puede usar isAssignableFrom para verificar el tipo.
Cada vez que crea una instancia de su objeto, tendría que repetirlo:
Podrías decidir que no vale la pena. En la implementación de ArrayList.indexOf (...) , no verifican que el tipo coincida.
Opción 2: dejar que falle
Si necesita utilizar un método abstracto que requiera su tipo desconocido, entonces todo lo que realmente desea es que el compilador deje de llorar por la instancia de . Si tienes un método como este:
Puedes usarlo así:
Estás lanzando el objeto a T (tu tipo genérico), solo para engañar al compilador. Su conversión no hace nada en tiempo de ejecución , pero aún obtendrá una ClassCastException cuando intente pasar el tipo de objeto incorrecto a su método abstracto.
NOTA 1: Si está realizando conversiones adicionales no verificadas en su método abstracto, sus ClassCastExceptions quedarán atrapadas aquí. Eso podría ser bueno o malo, así que piénselo bien.
NOTA 2: Obtiene una comprobación nula gratuita cuando utiliza instanceof . Como no puede usarlo, es posible que deba verificar si es nulo con sus propias manos.
fuente
Publicación anterior, pero una forma simple de hacer una instancia genérica de verificación.
fuente
Siempre que su clase extienda una clase con un parámetro genérico, también puede obtener esto en tiempo de ejecución mediante reflexión, y luego usarlo para comparar, es decir
En el caso anterior, en tiempo de ejecución obtendrá String.class de getParameterizedClass (), y se almacena en caché para que no obtenga ningún reflejo sobrecarga en múltiples comprobaciones. Tenga en cuenta que puede obtener los otros tipos parametrizados por índice desde el método ParameterizedType.getActualTypeArguments ().
fuente
Tuve el mismo problema y aquí está mi solución (muy humilde, @george: esta vez compilando Y trabajando ...).
Mi probem estaba dentro de una clase abstracta que implementa Observer. La actualización del método de incendios Observable (...) con la clase Object que puede ser cualquier tipo de Object.
Solo quiero manejar objetos del tipo T
La solución es pasar la clase al constructor para poder comparar tipos en tiempo de ejecución.
Para la implementación solo tenemos que pasar la clase al constructor
fuente
O podría atrapar un intento fallido de lanzar en E, por ejemplo
fuente
Técnicamente no debería tener que hacerlo, ese es el punto de los genéricos, por lo que puede hacer una verificación de tipo de compilación:
pero luego el @Override puede ser un problema si tiene una jerarquía de clases. De lo contrario, vea la respuesta de Yishai.
fuente
El tipo de tiempo de ejecución del objeto es una condición relativamente arbitraria para filtrar. Sugiero mantener esa suciedad lejos de su colección. Esto se logra simplemente haciendo que su colección delegue en un filtro pasado en una construcción.
fuente
Comparator
o similar.)