2012-04-15 12 views
5

Così ho questa interfacciaTipo La cancellatura alza la sua brutta testa, come aggirare?

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

e voglio ricavare le classi per esso che gestiscono gli eventi, in questo modo:

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

Sopra esempio funziona bene. Ma il compilatore non mi consentirà di implementare EventHandler più volte, a causa della cancellazione del tipo estremamente frustrante .

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

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

Molte domande ...

  1. Perché Java non permettono la cancellazione di tipo? IIRC è qualcosa a che fare con l'essere compatibile con le versioni precedenti di Java, corretto?

EDIT: Voglio dire, perché non Java ha Tipo Erasure (avuto il contrario)

  1. C'è qualche sorta di "mod"/"estensione" (per mancanza di una parola migliore) o linguaggi di programmazione che mi consentono di aggirare il tipo di cancellazione? Poiché non sto utilizzando versioni precedenti di Java, non mi interessa che il mio codice sia compatibile con il codice precedente.

  2. Esistono soluzioni alternative, all'interno del linguaggio Java, che è possibile utilizzare per aggirare il tipo di cancellazione?

  3. In caso negativo, quali sono alcuni modi alternativi per codificare la gestione degli eventi nel mio programma che mantiene il compilatore felice?

+4

-- non ha senso. Java consente la cancellazione dei tipi, infatti implementa la cancellazione dei tipi. – emory

+0

"Esiste una sorta di" mod "/" estensione "(per mancanza di una parola migliore) o di linguaggi di programmazione che mi permettono di aggirare la cancellazione del tipo?" - Sì, molte lingue non hanno cancellazioni di tipi. – emory

+1

Stai cercando C# –

risposta

1

io non sono sicuro che la vostra comprensione della cancellazione del tipo in Java è corretta. Come spiegato here, il tipo della classe generica viene perso in fase di runtime.

In risposta alle tue domande:

  1. Penso che lei abbia ragione che Java implementa tipo di cancellazione per abilitare la compatibilità con le versioni precedenti del langauge.
  2. No, non penso ci sia un "mod".
  3. No non ci sono soluzioni alternative (i tipi vengono rimossi al momento della compilazione), ma è possibile utilizzare la riflessione.
  4. Vedi sotto.

penso che una soluzione più semplice sarebbe quella di così qualcosa come questo: "Perché Java non permette 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

cancellazione del tipo è bello, perché significa che la JVM non ha bisogno di sapere nulla di tipi generici. Ciò significa anche che non vi è alcun impatto sulle prestazioni dall'uso di tipi generici.

Inoltre, la tua idea circa la necessità di mantenere la compatibilità binaria è azzeccata (come indicato nello Type Erasure tutorial). La cancellazione dei caratteri consente il codice scritto prima che Java consentisse che i tipi generici interagissero perfettamente con il codice Java scritto utilizzando Generics.

Che ne dici di creare semplicemente due gestori e di collegarli entrambi?

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 possibilità è quella di utilizzare un GuavaEventBus di inviare gli eventi ai sottoscrittori. È specificamente progettato per risolvere il problema che stai affrontando, tra le altre cose.

Con esso, non è necessario implementare tutte le interfacce ... si limita a fornire due @Subscribe metodi come questo:

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

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

Alcuni documentazione aggiuntiva su di esso è disponibile sul Guava wiki.

1
  1. Sì, tipo la cancellazione viene implementato in modo tale che le specifiche del JVM non devono cambiare in modo da eseguire la nuova versione (uno dei generici di attuazione).

  2. Come altri rilevare molte lingue fanno tipo non implment cancellazione. Se siete alla ricerca all'interno di Java, forse, ma non sono sicuro - non non funzionerà sulla JVM standard, proprio a causa di 1.

  3. Si può fare un gestore di eventi generico:

.

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 
    } 
    } 
} 

Non il più elegante, ma funziona :)

+2

È possibile sbarazzarsi di questa catena "if instanceof ..." implementando il pattern di progettazione Visitor e il doppio invio. –

Problemi correlati