Peut-on éviter les avertissements non contrôlés lors du remplacement d'une méthode avec des paramètres de type brut?

StackOverflow https://stackoverflow.com/questions/241539

Question

J'étends une classe définie dans une bibliothèque que je ne peux pas modifier:

public class Parent
{
    public void init(Map properties) { ... }
}

Si je définis une classe "Enfant" qui étend Parent et que j'utilise Java 6 avec des génériques, quel est le meilleur moyen de remplacer la méthode init sans obtenir d'avertissements non contrôlés?

public class Child extends Parent
{
    // warning: Map is a raw type. References to generic type Map<K,V> should be parameterized
    public void init(Map properties) { }
}

Si j'ajoute des paramètres génériques, je reçois:

   // error: The method init(Map<Object,Object>) of type Child has the same erasure as init(Map) of type Parent but does not override it
   public void init(Map<Object,Object>) { ... }
   // same error
   public void init(Map<? extends Object,? extends Object>) { ... }
   // same error
   public void init(Map<?,?>) { ... }

Cette erreur se produit que j'utilise un type spécifique, un caractère générique lié ou un caractère générique non lié. Existe-t-il un moyen correct ou idiomatique de remplacer une méthode non générique sans avertissements et sans utiliser @SuppressWarnings (& "; Non coché &";)?

Était-ce utile?

La solution

Oui, vous devez déclarer la méthode de substitution avec la même signature que dans la classe parent, sans ajouter d'informations génériques.

Je pense que votre meilleur choix est d'ajouter l'annotation @SuppressWarnings("unchecked") au paramètre de type brut, et non à la méthode, pour ne pas supprimer les avertissements génériques que vous pourriez avoir dans votre propre code.

Autres conseils

Réponse courte: impossible de le faire.

Réponse insatisfaisante: désactivez les avertissements (spécifiques) dans votre IDE / build.xml.

Si vous ne pouvez pas modifier la bibliothèque, hélas, vous devez vous en tenir à des méthodes non génériques.

Le problème est que, malgré l'effacement du type, les deux init () ont la même signature, mais il peut en fait s'agir de méthodes différentes, ou identiques (*). Le compilateur ne peut pas dire s'il doit annuler ou surcharger, il est donc interdit.

(*) Supposons que le développeur de la bibliothèque voulait dire init (Map & Lt; String, Integer & Gt;). Vous allez maintenant implémenter init (Map & Lt; String, String & Gt;). C’est une surcharge, et deux méthodes devraient exister dans la vtable de la classe Child.

Mais que se passe-t-il si le développeur de la bibliothèque voulait dire init (Map < String, String >)? Ensuite, elle est écrasante et votre méthode doit remplacer l'init initial dans la classe Child, et il n'y aurait qu'une seule méthode dans la vtable de Child.

P.S. Je déteste comment les génériques mis en œuvre en Java: - (

Je pense que la réponse ci-dessus voulait dire @SuppressWarnings (& "; rawtypes &";) à la place.

Vous devez déclarer la méthode avec la même signature que le parent et vous recevrez donc des avertissements lors de la compilation. Vous pouvez les supprimer avec @SuppressWarnings (& "; Décoché &";)

La raison pour laquelle il n’existe aucun moyen de s’en débarrasser, c’est que les avertissements sont là pour vous faire savoir qu’il est possible de créer des collections contenant des types non valides. Les avertissements ne doivent disparaître que lorsque tout le code susceptible de permettre cela a été supprimé. Comme vous héritez d'une classe non générique, il sera toujours possible de créer une collection avec un contenu non valide.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top