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


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

Il semble qu'il serait exagéré de marquer chaque méthode surchargée avec le @Override annotation. Y a-t-il des situations de programmation nécessitant l'utilisation de @Override et d'autres qui ne devraient jamais utiliser le @Override?


498
2017-09-18 16:48


origine


Réponses:


Utilisez-le chaque fois que vous remplacez une méthode pour deux avantages. Faites-le de sorte que vous puissiez tirer parti de la vérification du compilateur pour vous assurer que vous écrasez réellement une méthode lorsque vous le pensez. De cette façon, si vous faites une erreur courante en mal orthographiant un nom de méthode ou en ne correspondant pas correctement aux paramètres, vous serez averti que votre méthode ne remplace pas réellement ce que vous pensez. Deuxièmement, cela facilite la compréhension de votre code, car il est plus évident lorsque les méthodes sont écrasées.

De plus, dans Java 1.6, vous pouvez l'utiliser pour marquer quand une méthode implémente une interface pour 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
2017-09-18 16:53



Je pense qu'il est très utile comme rappel de 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. C'est un détail d'implémentation important de cette classe - nous ne voulons pas que les informations sensibles soient affichées.

Supposons que cette méthode est modifiée dans la classe parent pour

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

Cette modification ne provoquera pas d'erreurs de temps de compilation ou d'avertissements, mais elle modifie complètement le comportement prévu de la sous-classe.

Pour répondre à votre question: vous devriez utiliser l'annotation @Override si l'absence d'une méthode avec la même signature dans une super-classe indique un bogue.


110
2017-09-18 16:56



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

Il n'y a pas d'overkill lorsque vous codez. Il ne vous coûte rien de taper @override, mais les économies peuvent être énormes si vous avez mal orthographié le nom d'une méthode ou si la signature est légèrement incorrecte.

Pensez-y de cette façon: au moment où vous avez navigué ici et tapé cet article, vous avez utilisé à peu près plus de temps que vous ne passerez à taper @override pour le reste de votre vie; mais une erreur qu'il empêche peut vous sauver des heures.

Java fait tout ce qui est en son pouvoir pour s'assurer que vous ne faites pas d'erreur au moment de l'édition / de la compilation, c'est un moyen pratiquement gratuit de résoudre toute une classe d'erreurs qui ne peuvent être évitées en dehors des tests complets.

Pourriez-vous proposer un meilleur mécanisme en Java pour vous assurer que lorsque l'utilisateur avait l'intention de remplacer une méthode, il l'a fait?

Un autre effet intéressant est que si vous ne fournissez pas l'annotation, il vous avertira au moment de la compilation que vous avez accidentellement remplacé une méthode parente, ce qui pourrait être important si vous n'aviez pas l'intention de le faire.


46
2017-09-18 18:40



J'utilise toujours la balise. C'est un simple drapeau de compilation pour attraper les petites erreurs que je pourrais faire.

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

Les petites choses aident dans les grands projets.


22
2017-09-18 16:50



En utilisant le @Override L'annotation agit comme une sauvegarde à la compilation contre une erreur de programmation commune. Il va lancer une erreur de compilation si vous avez l'annotation sur une méthode que vous n'êtes pas en train de surcharger la méthode de la super-classe.

Le cas le plus fréquent 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 a utilisé pour surcharger la méthode de superclasse 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. le @Override des protections d'annotation contre cela.


18
2017-09-18 16:54



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 ne permettra pas cette annotation lors du remplacement des méthodes d'interface. Vous pouvez juste l'utiliser pour remplacer les méthodes de classe (abstraites ou non).

Certains IDE, comme Eclipse, même configurés avec Java 1.6 ou supérieur, respectent Java 1.5 et n'autorisent pas l'utilisation de @override comme décrit ci-dessus. Pour éviter ce comportement, 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 remplace une méthode indépendamment, si la base est une interface, ou une classe.

Cela vous permet d'éviter certaines erreurs typiques, comme lorsque vous pensez que vous êtes en train de remplacer un gestionnaire d'événements et que rien ne se passe. Imaginez que vous souhaitiez ajouter un écouteur d'événement à un composant de l'interface utilisateur:

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

Le code ci-dessus compile et s'exécute, mais si vous déplacez la souris dans someUIComponent, le code "do something" sera exécuté, car en réalité vous ne surchargez 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é le @Override annotation vous avez vu une erreur de compilation et vous n'avez pas perdu de temps à penser que votre gestionnaire d'événements ne fonctionnait pas.


14
2017-09-16 13:47



@Override sur implémentation d'interface est incohérent puisqu'il n'y a pas de "remplacement d'une interface" en Java.

@Override sur implémentation d'interface est inutile puisque dans la pratique, il ne capte aucun bogue que la compilation n'attraperait de toute façon. Il existe un seul scénario, tiré par les cheveux, où le remplacement sur les implémenteurs fait quelque chose: 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 a des méthodes NEW ou CHANGED, vous obtiendrez évidemment une erreur de compilation de toute façon car vous n'appliquez pas les nouveaux éléments.

@Override sur les implémenteurs d'interface ne devrait jamais avoir été autorisé en 1.6, et avec eclipse choisissant malheureusement d'insérer automatiquement les annotations comme comportement par défaut, nous obtenons beaucoup de fichiers sources encombrés. Lorsque vous lisez le code 1.6, vous ne pouvez pas voir à partir de l'annotation @Override si une méthode remplace réellement une méthode dans la superclasse ou implémente simplement une interface.

L'utilisation de @Override lors du remplacement d'une méthode dans une superclasse est correcte.


8
2017-09-02 14:44



Il est préférable de l'utiliser pour chaque méthode destinée à remplacer, et Java 6+, chaque méthode conçue comme une implémentation d'une interface.

D'abord, il prend des fautes d'orthographe comme "hashcode()" au lieu de "hashCode()"au moment de la compilation. Il peut être déroutant de déboguer pourquoi le résultat de votre méthode ne semble pas correspondre à votre code lorsque la cause réelle est que votre code n’est jamais invoqué.

En outre, si une super-classe modifie une signature de méthode, les remplacements de l'ancienne signature peuvent être "orphelins", laissant un code mort confus. le @Override L'annotation vous aidera à identifier ces orphelins afin qu'ils puissent être modifiés pour correspondre à la nouvelle signature.


8
2017-09-18 18:00



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

Utiliser @Override lors de l'implémentation des méthodes d'interface (fonctionnalité 1.6+) me semble un peu trop compliqué. Si vous avez des tas de méthodes dont certaines se substituent et d'autres non, ce sera probablement une mauvaise conception (et votre éditeur montrera probablement ce qui est ce que vous ne savez pas).


7
2017-09-18 16:54



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


7
2017-09-18 17:37