Remplacement d’une méthode avec des parameters génériques en Java?

J’ai une classe abstraite Monitor.java qui est sous- classée par une classe EmailMonitor.java .

La méthode:

public abstract List performMonitor(List accounts) 

est défini dans Monitor.java et doit être remplacé dans EmailMonitor.java .

J’ai actuellement la méthode remplacée dans EmailMonitor.java comme suit:

 @Override public List performMonitor(List emailAccounts) { //...unrelated logic return emailAccounts; } 

Cependant, cela produit l’erreur de compilation:

Name clash: The method performMonitor(List) of type EmailMonitor has the same erasure as performMonitor(Lis emailAccounts) of type Monitor but does not override it

EmailAccount est une sous-classe de MonitorAccount , donc (dans mon esprit du moins) le remplacer de cette manière est parfaitement logique. Vu que le compilateur n’est pas satisfait de ma logique, comment dois-je procéder correctement tout en conservant mes vérifications de compilation pour m’assurer que tous les appels à EmailMonitor.performMonitor() reçoivent des listes de EmailAccount plutôt qu’un autre type de MonitorAccount ?

Non, ce n’est pas le cas. La substitution signifie que vous devez être capable de gérer toute entrée valide dans la classe de base. Considérez ce qui se passerait si un client faisait ceci:

 Monitor x = new EmailMonitor(); List nonEmailAccounts = ...; x.performMonitor(nonEmailAccounts); 

Il n’y a rien là-dedans qui devrait donner une erreur de compilation en fonction de votre description – mais c’est clairement faux.

Il me semble que Monitor devrait être générique dans le type de compte qu’il peut surveiller, donc votre EmailMonitor devrait étendre Monitor . Alors:

 public abtract class Monitor { ... public abstract List performMonitor( List accounts); } public class EmailMonitor extends Monitor { @Override public abstract List performMonitor( List accounts) { // Code goes here } } 

Vous voudrez peut-être bien réfléchir aux génériques de l’appel performMonitor – quelle est la valeur de retour à signifier?

Voici ma propre solution. Je soupçonne que c’est la même chose que Jon Skeet essayait de faire … sans la faute de frappe (voir mon commentaire en réponse à sa réponse).

la classe Monitor.java :

 public abstract class Monitor  { ... public abstract List performMonitor(List accounts); .. } 

EmailMonitor.java

 public class EmailMonitor extends Monitor { ... public List performMonitor(List emailAccounts) { ..//logic...logic...logic return emailAccounts; } ... } 

Dans cette configuration, EmailMonitor.performMonitor () vérifiera toujours au moment de la compilation qu’il reçoit une liste de EmailAccount plutôt qu’un de mes autres types FTPAccount, DBAccount, etc … envoi d’une liste brute, puis contrainte de le forcer sur le type requirejs, ce qui entraîne des exceptions de transtypage de type à l’exécution.