web-dev-qa-db-fra.com

Quel est le gain de déclarer une méthode comme statique

J'ai récemment parcouru mes avertissements dans Eclipse et je suis tombé sur celui-ci:

static warning

Il donnera un avertissement au compilateur si la méthode peut être déclarée comme statique.

[edit] Citation exacte dans l'aide d'Eclipse, en mettant l'accent sur le privé et le final:

Lorsqu'il est activé, le compilateur émettra une erreur ou un avertissement pour les méthodes private ou final et qui se réfèrent uniquement aux membres statiques.

Oui, je sais que je peux l'éteindre, mais je veux connaître la raison de l'allumer?

Pourquoi serait-ce une bonne chose de déclarer chaque méthode possible comme statique?

Cela donnera-t-il des avantages en termes de performances? (dans un domaine mobile)

Soulignant une méthode comme statique, je suppose que cela montre que vous n'utilisez pas de variables d'instance et que vous pourriez donc être déplacé vers une classe de style utils?

À la fin de la journée, dois-je simplement désactiver cette option "ignorer" ou dois-je corriger les 100+ avertissements qu'elle m'a donnés?

Pensez-vous que ce ne sont que des mots-clés supplémentaires qui salissent le code, car le compilateur va juste incorporer ces méthodes de toute façon? (un peu comme si vous ne déclariez pas toutes les variables que vous pouvez finaliser mais vous pourriez ).

93
Blundell

Chaque fois que vous écrivez une méthode, vous remplissez un contrat dans une portée donnée. Plus l'étendue est étroite, plus les chances sont faibles d'écrire un bogue.

Lorsqu'une méthode est statique, vous ne pouvez pas accéder aux membres non statiques; par conséquent, votre portée est plus étroite. Donc, si vous n'avez pas besoin de et n'aurez jamais besoin (même dans les sous-classes) de membres non statiques pour remplir votre contrat , pourquoi donner accès à ces champs à votre méthode? La déclaration de la méthode static dans ce cas permettra au compilateur de vérifier que vous n'utilisez pas de membres que vous n'avez pas l'intention d'utiliser.

De plus, cela aidera les personnes qui liront votre code à comprendre la nature du contrat.

C'est pourquoi il est bon de déclarer une méthode static lorsqu'elle implémente réellement un contrat statique.

Dans certains cas, votre méthode ne signifie que quelque chose par rapport à une instance de votre classe, et il arrive que son implémentation n'utilise en fait aucun champ ou instance non statique. Dans de tels cas, vous ne marquerez pas la méthode static.

Exemples de cas où vous n'utiliseriez pas le mot clé static:

  • Un crochet d'extension qui ne fait rien (mais pourrait faire quelque chose avec les données d'instance dans une sous-classe)
  • Un comportement par défaut très simple censé être personnalisable dans une sous-classe.
  • Implémentation du gestionnaire d'événements: l'implémentation variera selon la classe du gestionnaire d'événements mais n'utilisera aucune propriété de l'instance du gestionnaire d'événements.
130
Samuel Rossille

Il n'y a pas de concept d'optimisation ici.

Une méthode static est static car vous déclarez explicitement que cette méthode ne dépend d'aucune instance de la classe englobante simplement parce qu'elle n'en a pas besoin. Donc, cet avertissement Eclipse, comme indiqué dans la documentation:

Lorsqu'il est activé, le compilateur émet une erreur ou un avertissement pour les méthodes qui sont privées ou finales et qui se réfèrent uniquement aux membres statiques.

Si vous n'avez besoin d'aucune variable d'instance et que votre méthode est privée (ne peut pas être appelée de l'extérieur) ou finale (ne peut pas être remplacée), il n'y a aucune raison de la laisser être une méthode normale au lieu d'une méthode statique. Une méthode statique est intrinsèquement plus sûre même parce que vous êtes autorisé à en faire moins (elle n'a besoin d'aucune instance, vous n'avez pas d'objet this implicite).

13
Jack

Je n'ai aucune information sur les performances, je suppose que c'est un peu mieux au mieux, car le code n'a pas besoin de faire de répartition dynamique en fonction du type.

Cependant, un argument beaucoup plus fort contre la refactorisation en méthodes statiques est que l'utilisation actuelle de la statique est considérée comme une mauvaise pratique. Les méthodes/variables statiques ne s'intègrent pas bien dans un langage orienté objet et sont également difficiles à tester correctement. C'est la raison pour laquelle certains langages plus récents renoncent complètement au concept de méthodes/variables statiques, ou tentent de l'intérioriser dans le langage d'une manière qui joue mieux avec OO (par exemple, les objets dans Scala).

La plupart du temps, vous avez besoin de méthodes statiques pour implémenter des fonctions qui n'utilisent que des paramètres en entrée et produisent une sortie en utilisant cela (par exemple, les fonctions utilitaires/auxiliaires). Dans les langages modernes, il existe un concept de fonction de première classe qui permet cela, donc statique n'est pas nécessaire. Java 8 aura des expressions lambda intégrées, donc nous allons déjà dans cette direction.

6
Istvan Devai

1. La méthode de déclaration static offre un léger avantage en termes de performances, mais ce qui est plus utile, elle permet de l'utiliser sans avoir d'instance d'objet à portée de main (pensez par exemple à la méthode d'usine ou à l'obtention d'un singleton). Il sert également à documenter la nature de la méthode. Cet objectif documentaire ne doit pas être ignoré, car il donne un aperçu immédiat de la nature de la méthode aux lecteurs du code et aux utilisateurs de l'API et sert également d'outil de réflexion pour le programmeur d'origine - être explicite sur la signification souhaitée aide vous pensez aussi directement et produisez un code de meilleure qualité (je pense que d'après mon expérience personnelle, mais les gens sont différents). Par exemple, il est logique et donc souhaitable de faire la distinction entre les méthodes opérant sur un type et les méthodes agissant sur une instance du type (comme souligné par Jon Skeet dans son commentaire à une question C # ).

Un autre cas d'utilisation des méthodes static est d'imiter l'interface de programmation procédurale. Pensez à la classe Java.lang.System.println() et aux méthodes et attributs qu'elle contient. La classe Java.lang.System est utilisé comme un espace de nom de regroupement plutôt qu'un objet instanciable.

2. Comment Eclipse (ou tout autre type d’entité - biocomposable ou non-biocomposable -) peut-il savoir avec certitude quelle méthode pourrait être déclarée comme statique? Même si une classe de base n'accède pas aux variables d'instance ou n'appelle pas de méthodes non statiques, par le mécanisme de l'héritage, les choses peuvent changer. Ce n'est que si la méthode ne peut pas être remplacée en héritant de la sous-classe, que nous pouvons affirmer avec 100% de certitude que la méthode peut vraiment être déclarée static. Remplacer une méthode est impossible exactement dans les deux cas

  1. private (aucune sous-classe ne peut l'utiliser directement et ne le sait même pas en principe), ou
  2. final (même si accessible par la sous-classe, il n'y a aucun moyen de changer la méthode pour faire référence aux données ou fonctions d'instance).

D'où la logique de l'option Eclipse.

3. L'affiche originale demande également: " Soulignant une méthode comme statique, je suppose que cela montre que vous n'utilisez aucune instance les variables pourraient donc être déplacées dans une classe de style utils? "C'est un très bon point. Parfois, ce type de modification de conception est indiqué par l'avertissement.

C'est une option très utile, que je veillerais personnellement à activer, si j'utilisais Eclipse et si je programmais en Java.

3
FooF

Voir la réponse de Samuel sur la façon dont la portée de la méthode change. Je suppose que c'est l'aspect principal de la statique d'une méthode.

Vous avez également posé des questions sur les performances:

Il peut y avoir un petit gain de performances, car un appel à une méthode statique n'a pas besoin de la référence implicite "this" comme paramètre.

Cependant, cet impact sur les performances est vraiment minime. Par conséquent, tout dépend de la portée.

1
Black

Depuis le Android Consignes de performance:

Préférez statique à virtuel Si vous n'avez pas besoin d'accéder aux champs d'un objet, rendez votre méthode statique. Les invocations seront environ 15% à 20% plus rapides. C'est également une bonne pratique, car vous pouvez dire à partir de la signature de la méthode que l'appel de la méthode ne peut pas modifier l'état de l'objet.

http://developer.Android.com/training/articles/perf-tips.html#PreferStatic

1
Blundell

Eh bien, la documentation Eclipse dit à propos de l'avertissement en question:

La méthode peut être statique

Lorsqu'il est activé, le compilateur émet une erreur ou un avertissement pour les méthodes qui sont privées ou finales et qui se réfèrent uniquement aux membres statiques

Je pense que cela dit à peu près tout. Si la méthode est privée et finale et ne se réfère qu'aux membres statiques, la méthode en question pourrait tout aussi bien être déclarée statique et, par là, montrer que nous avons uniquement l'intention d'accéder au contenu statique à partir de celle-ci.

Honnêtement, je ne pense pas qu'il y ait une autre raison mystérieuse derrière cela.

0
Edwin Dalorzo