2013-03-26 4 views
3

J'ai une question concernant la signature de méthode correcte dans l'interface, et pourquoi. Mon événement est paramétré avec un type, cependant l'interface doit-elle aussi avoir un <T> qui l'utilise dans la signature de la méthode? Si oui, pourquoi, pourquoi pas?Utilisation de génériques dans l'interface

public interface MyListener { 
    void beforeAction(final MyEvent event); 
} 

Et

public class MyEvent<T> extends EventObject { 

    // code 
} 

Répondre

4

Si MyEvent est paramétrés avec un type, alors MyListener devront être spécifié comme

public interface MyListener<T> { 
    void beforeAction(final MyEvent<T> event); 
} 

ou s'il existe différents types de MyEvents qui ne sont pas spécifique à l'enceinte MyListener, puis:

public interface MyListener { 
    <T> void beforeAction(final MyEvent<T> event); 
} 

Ou, comme dit Thomas, vous pouvez simplement ignorer le type de T au total:

public interface MyListener { 
    void beforeAction(final MyEvent<?> event); 
} 

Vous devrez faire un de ce qui précède, ou vous obtiendrez un compilateur d'avertissement sur l'utilisation de types bruts.

+1

Ou si 'T' n'a pas d'importance dans ce cas, vous pouvez faire' void beforeAction (événement final MyEvent ); ' – Thomas

+1

Pourriez-vous expliquer pourquoi aussi? – LuckyLuke

+0

Je ne pense pas qu'il y ait vraiment une raison pour laquelle d'autres que cela supprime les avertissements du compilateur, et vous permet en quelque sorte d'imposer des contraintes de type au moment de la compilation. Aucune information de type n'est stockée lors de l'exécution. Comme vous le verrez dans [des questions comme celle-ci] (http://stackoverflow.com/q/15629552/586086), le système générique de Java est complètement détruit. –

2

Si le type de T n'a pas d'importance dans votre programme d'écoute, vous devez au moins définir la méthode comme void beforeAction(final MyEvent<?> event); afin de vous débarrasser de l'avertissement et de conserver les génériques activés. Sans aucun type, le compilateur désactivera tous les contrôles de type pour cette méthode.

Si vous souhaitez avoir des écouteurs différents pour différents types d'événements, vous devez également ajouter le T à votre interface, comme Andrew l'a déjà signalé. De cette façon, vous pouvez créer plusieurs implémentations d'écouteur sans nécessiter de conversions manuelles (et donc de bogues), par ex. quelque chose comme ceci:

public class StringListener implements MyListener<String> { 
    void beforeAction(final MyEvent<String> event) { 
    ... 
    } 
} 

public class NumberListener implements MyListener<Number> { 
    void beforeAction(final MyEvent<Number> event) { 
    ... 
    } 
} 

Si vous avez mises en œuvre comme celle-ci, vous pouvez également interroger la valeur de T lors de l'exécution, puisque ces informations de type sont stockées dans les données de réflexion. Notez que cela n'est pas vrai pour les classes anonymes ou les variables locales - dans ce cas, l'effacement du type a lieu.

+0

Me recommanderiez-vous d'avoir le 'T' dans l'écouteur ou d'utiliser'? ' – LuckyLuke

+0

@LuckyLuke qui dépend réellement de ce que vous voulez faire avec cette interface. Dans la plupart des cas, je préférerais ajouter le 'T' à l'interface et le définir dans l'implémentation comme illustré ci-dessus. – Thomas

Questions connexes