web-dev-qa-db-fra.com

Quand utilisez-vous l'annotation @Override de Java et pourquoi?

Quelles sont les meilleures pratiques pour utiliser l'annotation @Override de Java et pourquoi?

Il semble exagéré de marquer chaque méthode surchargée avec l'annotation @Override. Existe-t-il certaines situations de programmation qui nécessitent l’utilisation du @Override et d’autres qui ne devraient jamais utiliser le @Override?

498
Alex B

Utilisez-le chaque fois que vous substituez une méthode pour deux avantages. Faites-le pour que vous puissiez profiter de la vérification du compilateur pour vous assurer que vous surchargez une méthode lorsque vous pensez le faire. Ainsi, si vous commettez souvent l'erreur de mal orthographier le nom d'une méthode ou de ne pas faire correspondre correctement les paramètres, vous serez averti que votre méthode ne remplace pas réellement ce que vous pensez. Deuxièmement, cela rend votre code plus facile à comprendre car il est plus évident lorsque les méthodes sont écrasées.

De plus, dans Java 1.6, vous pouvez l'utiliser pour indiquer quand une méthode implémente une interface avec les mêmes avantages. Je pense qu'il serait préférable d'avoir une annotation séparée (comme @Implements), mais c'est mieux que rien.

515
Dave L.

Je pense qu'il est très utile de rappeler à la compilation que l'intention de la méthode est de remplacer une méthode parente. Par exemple:

protected boolean displaySensitiveInformation() {
  return false;
}

Vous verrez souvent quelque chose comme la méthode ci-dessus qui remplace une méthode dans la classe de base. Il s'agit d'un détail d'implémentation important de cette classe - nous ne voulons pas que des informations sensibles soient affichées.

Supposons que cette méthode soit modifiée dans la classe parente

protected boolean displaySensitiveInformation(Context context) {
  return true;
}

Cette modification ne causera aucune erreur de temps de compilation ni aucun avertissement, mais modifiera complètement le comportement souhaité de la sous-classe.

Pour répondre à votre question: vous devez utiliser l'annotation @Override si l'absence d'une méthode avec la même signature dans une superclasse est révélatrice d'un bogue.

110
jon

Il y a beaucoup de bonnes réponses ici, alors laissez-moi vous proposer une autre façon de voir les choses ...

Il n'y a pas de surmenage lorsque vous codez. Taper @override ne vous coûte rien, mais les économies peuvent être considérables si vous mal orthographiez le nom d'une méthode ou si vous avez légèrement falsifié la signature.

Pensez-y de la manière suivante: pendant le temps où vous avez navigué ici et tapé ce message, vous avez utilisé plus de temps que nécessaire à taper @override pour le reste de votre vie; mais une erreur qu’elle évite peut vous faire économiser des heures.

Java fait tout ce qui est en son pouvoir pour s’assurer que vous n’avez commis aucune erreur au moment de l’édition/compilation, c’est un moyen pratiquement gratuit de résoudre toute une catégorie d’erreurs qui ne peuvent pas être évitées autrement que par des tests complets.

Pourriez-vous trouver un meilleur mécanisme dans Java pour vous assurer que lorsque l'utilisateur a l'intention de remplacer une méthode, il l'a réellement fait?

Un autre effet intéressant est que si vous ne fournissez pas l'annotation, elle vous avertira lors de la compilation que vous avez accidentellement surchargé une méthode parent - ce qui pourrait être significatif si vous n'aviez pas l'intention de le faire.

46
Bill K

J'utilise toujours l'étiquette. C'est un simple drapeau de compilation qui permet d'attraper les petites erreurs que je pourrais commettre.

Il va attraper des choses comme tostring() au lieu de toString()

Les petites choses aident dans les grands projets.

22
jjnguy

L’utilisation de l’annotation @Override sert de protection lors de la compilation contre une erreur de programmation courante. Une erreur de compilation se produira si vous avez l'annotation sur une méthode et que vous ne remplacez pas réellement la méthode superclass.

Le cas le plus courant où cela est utile est lorsque vous modifiez une méthode dans la classe de base pour avoir une liste de paramètres différente. Une méthode dans une sous-classe qui remplaçait la méthode superclass ne le fera plus en raison de la signature de la méthode modifiée. Cela peut parfois provoquer un comportement étrange et inattendu, en particulier lorsqu'il s'agit de structures d'héritage complexes. L'annotation @Override vous protège contre cela.

18
toluju

Pour tirer parti de la vérification du compilateur, vous devez toujours utiliser l'annotation Remplacer. Mais n'oubliez pas que Java Compiler 1.5 n'autorisera pas cette annotation lors de la substitution des méthodes d'interface. Vous pouvez simplement l'utiliser pour redéfinir les méthodes de classe (abstraites ou non).

Certains IDE, comme Eclipse, même configurés avec le runtime Java 1.6 ou supérieur, maintiennent la conformité avec Java 1.5 et n'autorisent pas l'utilisation de @override comme décrit ci-dessus. Pour éviter ce problème, vous devez accéder à: Propriétés du projet -> Compilateur Java -> Cochez la case "Activer les paramètres spécifiques au projet" -> Choisissez "Niveau de conformité du compilateur" = 6.0 ou supérieur.

J'aime utiliser cette annotation chaque fois que je redéfinis une méthode indépendamment, si la base est une interface ou une classe.

Cela vous aide à éviter certaines erreurs typiques, comme lorsque vous pensez que vous redéfinissez un gestionnaire d'événements et que rien ne se passe. Imaginez que vous souhaitiez ajouter un écouteur d'événement à un composant d'interface utilisateur:

someUIComponent.addMouseListener(new MouseAdapter(){
  public void mouseEntered() {
     ...do something...
  }
});

Le code ci-dessus est compilé et exécuté, mais si vous déplacez la souris à l'intérieur d'un composant UIComponent, le code "faire quelque chose" sera exécuté, car vous ne redéfinissez pas la méthode de base mouseEntered(MouseEvent ev). Vous venez de créer une nouvelle méthode sans paramètre mouseEntered(). Au lieu de ce code, si vous avez utilisé l'annotation @Override, vous avez constaté une erreur de compilation et vous n'avez pas perdu de temps à vous demander pourquoi votre gestionnaire d'événements ne s'exécutait pas.

14
user174340

Il est préférable de l’utiliser pour chaque méthode destinée à être remplacée et à Java 6+, chaque méthode destinée à être une implémentation d’une interface.

Tout d'abord, il récupère les fautes d'orthographe telles que "hashcode()" au lieu de "hashCode()" au moment de la compilation. Il peut être déconcertant de déboguer pourquoi le résultat de votre méthode ne semble pas correspondre à votre code alors que la cause réelle est que votre code n'est jamais appelé.

De plus, si une super-classe modifie une signature de méthode, les remplacements de la signature la plus ancienne peuvent être "orphelins", laissés comme un code mort source de confusion. L'annotation @Override vous aidera à identifier ces orphelins afin qu'ils puissent être modifiés pour correspondre à la nouvelle signature.

8
erickson

@Override on implémentation d'interface est incohérent car il n'y a pas de chose comme "écraser une interface" en Java.

@Override sur implémentation d'interface est inutile car dans la pratique, il ne détecte aucun bogue que la compilation ne détecterait pas de toute façon. Il n'y a qu'un seul scénario, très recherché, où le remplacement par les implémenteurs agit réellement: si vous implémentez une interface et les méthodes REMOVES de l'interface, vous serez averti au moment de la compilation que vous devez supprimer les implémentations inutilisées. Notez que si la nouvelle version de l'interface comporte des méthodes NEW ou CHANGED, vous obtiendrez évidemment une erreur de compilation de toute façon, car vous n'implémentez pas les nouveaux éléments.

@Override sur les implémenteurs d'interface n'aurait jamais dû être autorisé dans 1.6, et avec Eclipse choisissant malheureusement d'insérer automatiquement les annotations en tant que comportement par défaut, nous obtenons beaucoup de fichiers source encombrés. Lors de la lecture du code 1.6, l'annotation @Override ne permet pas de voir si une méthode remplace en réalité une méthode de la superclasse ou implémente simplement une interface.

Utiliser @Override pour redéfinir une méthode dans une super-classe est acceptable.

8
Rune

Une autre chose qu'il fait est que cela rend plus évident en lisant le code que cela change le comportement de la classe parente. Than peut aider au débogage.

De plus, dans le livre Effective de Joshua Block, Effective Java (2e édition), le point 36 donne plus de détails sur les avantages de l'annotation.

7
Diastrophism

@Override sur les interfaces est réellement utile, car vous obtiendrez des avertissements si vous modifiez l'interface.

7
Asgeir S. Nilsen

Si vous vous retrouvez souvent en train de surcharger des méthodes (non abstraites), vous voudrez probablement jeter un coup d'œil à votre conception. Il est très utile que le compilateur n’attrape pas l’erreur autrement. Par exemple, essayer de remplacer initValue () dans ThreadLocal, ce que j'ai fait.

Utiliser @Override lors de l'implémentation de méthodes d'interface (fonctionnalité 1.6+) semble un peu excessif pour moi. Si vous avez des tas de méthodes dont certaines remplacent et d'autres non, c'est probablement encore une mauvaise conception (et votre éditeur vous montrera probablement ce qui est si vous ne le savez pas).

7

Cela n'a aucun sens d'utiliser @Override lors de l'implémentation d'une méthode d'interface. Il n'y a aucun avantage à l'utiliser dans ce cas - le compilateur aura déjà compris votre erreur, c'est donc un fouillis inutile.

6
Steve R.

Chaque fois qu'une méthode remplace une autre méthode ou qu'une méthode implémente une signature dans une interface.

L'annotation @Override vous assure que vous avez en réalité ignoré quelque chose. Sans l'annotation, vous risquez une faute d'orthographe ou une différence dans les types et le nombre de paramètres.

6
Greg Mattes
  • Utilisé uniquement dans les déclarations de méthode.
  • Indique que la déclaration de méthode annotée remplace une déclaration en supertype.

S'il est utilisé de manière cohérente, il vous protège d'une grande classe de bogues néfastes.

Utilisez les annotations @Override pour éviter ces bugs: (Trouvez le bogue dans le code suivant :)

public class Bigram {
    private final char first;
    private final char second;
    public Bigram(char first, char second) {
        this.first  = first;
        this.second = second;
    }
    public boolean equals(Bigram b) {
        return b.first == first && b.second == second;
    }
    public int hashCode() {
        return 31 * first + second;
    }

    public static void main(String[] args) {
        Set<Bigram> s = new HashSet<Bigram>();
        for (int i = 0; i < 10; i++)
            for (char ch = 'a'; ch <= 'z'; ch++)
                s.add(new Bigram(ch, ch));
        System.out.println(s.size());
    }
}

source: Effective Java

5
jai

Je l'utilise à chaque fois. C'est plus d'informations que je peux utiliser pour comprendre rapidement ce qui se passe lorsque je revisite le code dans un an et que j'ai oublié ce que je pensais la première fois.

5
Hank Gay

Je l'utilise partout. En ce qui concerne l’effort de marquage, j’ai laissé Eclipse le faire pour moi, ce n’est donc pas un effort supplémentaire.

Je suis religieux au sujet de la refactorisation continue ... alors, je vais utiliser chaque petite chose pour que ça se passe mieux.

5
willCode4Beer

La meilleure pratique consiste à toujours l’utiliser (ou le laisser le IDE le remplir à votre place)

L’utilité de @Override est de détecter les changements dans les classes parentes qui n’ont pas été signalés dans la hiérarchie. Sans elle, vous pouvez changer une signature de méthode et oublier de modifier ses substitutions. Avec @Override, le compilateur la détectera pour vous.

Ce genre de filet de sécurité est toujours utile.

5
David Pierre

Faites attention lorsque vous utilisez Override, car vous ne pourrez pas faire de reverse engineering dans starUML par la suite. faire le uml en premier.

3
Horatiu Jeflea

Il semble que la sagesse change ici. Aujourd'hui, j'ai installé IntelliJ IDEA 9 et j'ai remarqué que son " inspection manquante @Override " capture désormais non seulement les méthodes abstraites implémentées, mais également les méthodes d'interface. Dans la base de code de mon employeur et dans mes propres projets, j'ai depuis longtemps l'habitude d'utiliser uniquement @Override pour les méthodes abstraites précédemment implémentées. Cependant, en repensant cette habitude, l'intérêt d'utiliser les annotations dans les deux cas devient évident. Bien que plus bavard, il protège contre le problème de la classe de base fragile (pas aussi grave que les exemples liés à C++) où le nom de la méthode d’interface change, orphelin la méthode d'implémentation éventuelle dans une classe dérivée.

Bien entendu, ce scénario est principalement une hyperbole; la classe dérivée ne compilerait plus, il manque maintenant une implémentation de la méthode d'interface renommée, et aujourd'hui on utiliserait probablement une opération de refactoring Rename Method pour traiter les base de code entière en masse.

Étant donné que l'inspection d'IDEA n'est pas configurable pour ignorer les méthodes d'interface implémentées, je vais aujourd'hui changer à la fois mes habitudes et les critères de révision du code de mon équipe.

2
seh

L'annotation @Override permet de vérifier si le développeur doit redéfinir la méthode correcte dans la classe ou l'interface parente. Lorsque le nom des méthodes de super change, le compilateur peut notifier ce cas, ce qui sert uniquement à maintenir la cohérence avec le super et la sous-classe.

En passant, si nous n’annonçons pas l’annotation @Override dans la sous-classe, mais que nous substituons certaines méthodes de la classe super, la fonction peut alors fonctionner comme celle-ci avec @Override. Mais cette méthode ne peut pas informer le développeur lorsque la méthode du super a été modifiée. Parce qu'il ne connaissait pas l'objectif du développeur - remplacer la méthode de super ou définir une nouvelle méthode?

Ainsi, lorsque nous voulons remplacer cette méthode pour utiliser le polymorphisme, il est préférable d’ajouter @Override au-dessus de la méthode.

2
lzlstyle

Je l'utilise autant que possible pour identifier le moment où une méthode est remplacée. Si vous regardez le langage de programmation Scala, ils ont également un mot-clé override. Je trouve ça utile.

1
Berlin Brown

je pense qu'il est préférable de coder le @override chaque fois que cela est autorisé. cela aide pour le codage. toutefois, pour ecipse Helios, soit sdk 5 ou 6, l'annotation @override des méthodes d'interface implémentées est autorisée. Quant à Galileo, que ce soit 5 ou 6, l'annotation @override n'est pas autorisée.

0
lwpro2

Pour moi, le @Override m'assure que la signature de la méthode est correcte. Si je mets dans l'annotation et que la méthode n'est pas orthographiée correctement, le compilateur se plaint de me faire savoir que quelque chose ne va pas.

0
Dale

Simple: lorsque vous souhaitez remplacer une méthode présente dans votre super-classe, utilisez l'annotation @Override pour effectuer un remplacement correct. Le compilateur vous avertira si vous ne le remplacez pas correctement.

0
Sree

Cela vous permet (bien, au compilateur) de détecter si vous avez mal orthographié le nom de la méthode que vous substituez.

0
JeeBee

Les annotations de substitution permettent de tirer parti du compilateur pour vérifier si vous substituez réellement une méthode de la classe parente. Il est utilisé pour notifier si vous faites une erreur telle qu'une erreur de mal orthographier un nom de méthode, une erreur de ne pas correspondre correctement aux paramètres

0
Siva

Les annotations fournissent des métadonnées sur le code au compilateur et l'annotation @Override est utilisée en cas d'héritage lorsque nous redéfinissons une méthode de la classe de base. Cela indique simplement au compilateur que vous substituez la méthode. Cela peut éviter certaines erreurs courantes que nous pouvons commettre, comme ne pas suivre la signature correcte de la méthode, ou mal orthographier le nom de la méthode, etc. C'est donc une bonne pratique d'utiliser l'annotation @Override.

0
gprathour