2012-04-15 10 views
5

Así que tienen esta interfazTipo Erasure levanta su cabeza fea, ¿cómo eludir?

public interface EventHandler<E extends EventObject> 
{ 
    public void handleEvent(E event); 
} 

y quiero derivar clases para controlar los eventos de él que, de este modo:

public class WorkingHandler implements EventHandler<MouseEvent> 
{ 
    public void handleEvent(MouseEvent event) 
    { 
     //handle event 
    } 
} 

El ejemplo de arriba funciona bien. Pero el compilador no me deja implementar EventHandler varias veces, debido al extremadamente frustrante Type Erasure.

public class NotWorkingHandler implements EventHandler<MouseEvent>, EventHandler<KeyEvent> 
{ 
    public void handleEvent(MouseEvent event) 
    { 
     //handle mouse event 
    } 

    public void handleEvent(KeyEvent event) 
    { 
     //handle key event 
    } 
} 

varias preguntas ...

  1. ¿Por qué Java no permiten Tipo Erasure? IIRC es algo relacionado con ser compatible con versiones anteriores de Java, ¿correcto?

EDIT: Quiero decir ¿por qué Java tiene el Tipo Erasure (lo tenía al revés)

  1. ¿Hay alguna especie de "mod"/"extensión" (a falta de una palabra mejor) o lenguajes de programación que me permiten sortear Type Erasure? Como no estoy usando versiones anteriores de Java, no me importa que mi código sea compatible con código anterior.

  2. ¿Existen soluciones provisionales, dentro del lenguaje Java, que pueda usar para evitar el borrado de tipos?

  3. Si no, ¿cuáles son algunas formas alternativas de programar el manejo de eventos en mi programa que mantienen al compilador satisfecho?

+4

-- no tiene sentido. Java permite el borrado de tipos, de hecho implementa borrado de tipos. – emory

+0

"¿Hay algún tipo de" mod "/" extensión "(por falta de una palabra mejor) o lenguajes de programación que me permitan sortear Type Erasure?" - Sí, muchos idiomas no tienen borrado de tipo. – emory

+1

Está buscando C# –

Respuesta

1

No estoy seguro de que su comprensión de Tipo Erasure en Java es correcta. Como se explica en here, el tipo de su clase genérica se pierde en el tiempo de ejecución.

En respuesta a sus preguntas:

  1. Creo que tienes razón en que Java implementa el tipo de borrado para permitir la compatibilidad con versiones anteriores del langauge.
  2. No, no creo que haya un "mod."
  3. No, no hay soluciones (los tipos se eliminan en tiempo de compilación), pero puede usar la reflexión.
  4. Vea a continuación.

creo que una solución más sencilla sería la de por lo menos así: "? ¿Por qué Java no permite Tipo Erase"

public class WorkingHandler implements EventHandler<EventObject> 
{ 
    public void handleEvent(EventObject event) 
    { 
     // handle event 
     if (event instanceof MouseEvent) 
      handleMouseEvent((MouseEvent) event); 
     ... 
    } 

    ... 

    private void handleMouseEvent(MouseEvent event) 
    { 
     // handle mice 
    } 
} 
2

Type Erasure es agradable porque significa que la JVM no necesita saber nada sobre tipos genéricos. Esto también significa que no hay impacto en el rendimiento al usar tipos genéricos.

Además, su noción sobre la necesidad de mantener la compatibilidad binaria es inmediata (como se indica en el Type Erasure tutorial). La borradura de tipo permite que el código escrito antes de Java permita que los tipos genéricos interactúen sin problemas con el código de Java escrito usando Generics.

¿Qué tal simplemente hacer dos manipuladores y unir ambos?

public class KeyHandler implements EventHandler<KeyEvent> 
{ 
    public void handleEvent(KeyEvent event) 
    { 
     //handle key event 
    } 
} 

public class MouseHandler implements EventHandler<MouseEvent> 
{ 
    public void handleEvent(MouseEvent event) 
    { 
     //handle mouse event 
    } 
} 
5

Una opción es utilizar un GuavaEventBus para publicar eventos a los suscriptores. Está específicamente diseñado para abordar el problema que enfrenta actualmente, entre otras cosas.

Con él, no es necesario para poner en práctica cualquier interfaz ... sólo proporciona dos métodos @Subscribe así:

@Subscribe 
public void handleKeyEvent(KeyEvent event) { ... } 

@Subscribe 
public void handleMouseEvent(MouseEvent event) { ... } 

Algunos documentación adicional sobre el mismo está disponible en la guayaba wiki.

1
  1. Sí, el tipo de borrado está implementado de manera que las especificaciones de la JVM no tienen que cambiar con el fin de ejecutar la nueva versión (uno genéricos de desarrollo).

  2. Como se ha señalado, muchos idiomas no implican el borrado de tipos. Si usted está buscando dentro de Java, posiblemente, pero no estoy seguro - no, no funcionará en las JVM estándar precisamente debido a 1.

  3. Usted puede hacer un controlador de eventos genéricos:

.

public class GenericHandler implements EventHandler<EventObject> 
{ 
    public void handleEvent(EventObject event) 
    { 
    if (event instanceof MouseEvent) { 
     MouseEvent mouseEvent = (MouseEvent) event; 
     //handle mouse event 
    } else if (event instanceof KeyboardEvent) { 
     KeyboardEvent keyboardEvent = (KeyboardEvent) event; 
     //handle keyboard event 
    } 
    } 
} 

No es el más elegante, pero funciona :)

+2

Puede deshacerse de esta cadena "if instanceof ..." implementando el patrón de diseño Visitor y el doble despacho. –

Cuestiones relacionadas