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:
public MyCollection<T>(Class<T> t) {
this.t = t;
}
Luego puede usar isAssignableFrom para verificar el tipo.
public int indexOf(Object o) {
if (
o != null &&
!t.isAssignableFrom(o.getClass())
) return -1;
//...
Cada vez que crea una instancia de su objeto, tendría que repetirlo:
new MyCollection<Apples>(Apples.class);
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:
protected abstract void abstractMethod(T element);
Puedes usarlo así:
public int indexOf(Object o) {
try {
abstractMethod((T) o);
} catch (ClassCastException e) {
//...
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.
Class.isAssignableFrom
.