En Java, est-il un inconvénient pour les méthodes statiques de classe?
Permet de supposer qu'une règle (ou une règle de pouce, de toute façon), a été imposée dans mon environnement de codage que toute méthode d'une classe qui n'a pas l'utiliser, de modifier, ou d'autres raisons, ont besoin toutes les variables d'instance pour faire son travail, être mis à la statique. Est-il inhérent à la compilation, l'exécution, ou tout autre inconvénient à le faire?
(édité pour plus de précisions)
Je sais que la question a été quelque peu ouvert et vague, donc je m'en excuse. Mon intention en posant était dans le contexte de la plupart des "helper" méthodes. Les classes utilitaires (avec le secteur privé CTORs donc ils ne peuvent pas être instanciées) que les titulaires pour les méthodes statiques, nous le faisons déjà. Ma question était plus dans la ligne de ces petites méthodes qui AIDENT à la classe principale de l'API.
Je pourrais avoir 4 ou 5 principales API/méthodes d'instance d'une classe qui font le vrai travail, mais dans le cours de ce processus, ils ont en commun certaines fonctionnalités qui peut être seulement de travailler sur les paramètres d'entrée de la méthode de l'API, et non pas l'état interne. Ce sont les sections de code que j'ai généralement sortir dans leurs propres méthodes d'assistance, et si ils n'ont pas besoin d'accéder à la classe de l'état, de les rendre statique.
Ma question était est-ce donc, en soi, une mauvaise idée, et si oui, pourquoi? (Ou pourquoi pas?)
- c'est à peu près la définition d'un
static
méthode en Java - non, il n'est pas. C'est la définition d'une méthode de peut être
static
. - En regardant les réponses jusqu'à maintenant, les gens sont plutôt divisés sur la question. Il sera intéressant de voir si la bonne réponse va flotter, un test de nice pour la DONC de la communauté. Que, ou Jon Skeet vont faire leur apparition, et les frapper hors du parc.
Vous devez vous connecter pour publier un commentaire.
Le principal inconvénient est que vous ne pouvez pas permuter, substituer ou de choisir les implémentations de méthode au moment de l'exécution.
static
.static
n'est PAS orientée objet concept (pour les raisons que vous parlez). Et en Java, il est près de 0 boost de performance pour les méthodes statiques vs méthodes membres (regardez dans compilé en byte code -- c'est une question de pousser un objet de référence de la pile, il faut être plusieurs picosecondes ou alors 🙂 de Plus, si vous utilisez réflexion avec des méthodes statiques, vous avez encore besoin de passernull
comme premier argument deinvoke()
.final
a l'inconvénient de ne pouvoir hériter de la classe, ou diriez-vous que c'est un avantage et le point de l'ensemble de la clé?À mon avis, il y a quatre raisons à éviter les méthodes statiques en Java. Ce n'est pas à dire que les méthodes statiques sont jamais échéant, uniquement pour dire qu'ils doivent généralement être évitée.
Comme d'autres l'ont souligné, les méthodes statiques ne peuvent pas être moqué dans un test unitaire. Si une classe est en fonction, par exemple,
DatabaseUtils.createConnection()
, alors que dépendant de la classe, et toutes les classes qui en dépendent, sera presque impossible à tester sans avoir une base de données ou une sorte de "test" drapeau dansDatabaseUtils
. Dans ce dernier cas, il semble que vous disposez de deux implémentations d'unDatabaseConnectionProvider
interface -- voir le point suivant.Si vous avez une méthode statique, son comportement s'applique à toutes les classes, partout. La seule façon de modifier son comportement de façon conditionnelle est de passer dans un drapeau en tant que paramètre à la méthode ou un ensemble statique drapeau quelque part. Le problème avec la première approche, c'est qu'il modifie la signature pour chaque appelant, et devient rapidement complexe et de plus en plus de drapeaux sont ajoutés. Le problème avec la deuxième approche est que vous vous retrouvez avec ce code dans tous les sens:
Un exemple d'une bibliothèque commune qui a rencontré ce problème est d'Apache Commons Lang: voir StringUtilsBean et ainsi de suite.
Objets sont chargés une fois par le chargeur de classe, ce qui signifie que vous pouvez réellement avoir plusieurs copies de vos méthodes statiques et variables statiques autour sans le vouloir, ce qui peut causer des problèmes. Cela n'a généralement pas d'importance autant avec les méthodes d'instance, parce que les objets sont éphémères.
Si vous avez des méthodes statiques qui font référence à des variables statiques, ceux séjour autour de la durée de vie du chargeur de classe et de ne jamais obtenir de ces ordures. Si ces accumulent de l'information (par exemple, les caches) et vous n'êtes pas prudent, vous pouvez exécuter en "fuites de mémoire" dans votre application. Si vous utilisez des méthodes d'instance au lieu de cela, les objets ont tendance à être de courte durée de vie et donc sont récupérées après un certain temps. Bien sûr, vous pouvez toujours entrer dans des fuites de mémoire avec les méthodes d'instance de trop! Mais c'est moins un problème.
Espère que ça aide!
PowerMockito
est possible de se moquer destatic method
.L'avantage de performance est probablement négligeable. Utiliser des méthodes statiques pour tout ce qui n'est pas dépendante de l'état. Ceci permet de clarifier le code, comme vous pouvez le voir immédiatement avec une méthode statique d'appel qu'il n'y a pas d'état de l'instance en cause.
J'aime vraiment cette question, comme cela a été un point, j'ai été débattu pendant les 4 dernières années de ma vie professionnelle. Méthode statique faire beaucoup de sens pour les classes qui ne sont pas porteurs d'aucun état. Mais dernièrement, j'ai été révisé mon bien qu'un peu.
Utilitaire de classes ayant des méthodes statiques est une bonne idée.
Les classes de Service comptable de la logique métier peut être apatride, dans de nombreux cas. Au départ, j'ai toujours ajouté des méthodes statiques, mais alors quand j'ai gagné plus de familiarité avec le framework Spring (et un peu plus de lecture générale), j'ai réalisé ces méthodes ne sont invérifiables comme une unité indépendante, u ne peut pas injecter de se moquer de services facilement dans cette classe. E. g. Une méthode statique qui appelle une autre méthode statique dans une autre classe, il n'y a aucun moyen de test JUnit peut court-circuiter les intermédiaires de confiance de chemin d'accès par l'injection d'un mannequin de mise en œuvre au moment de l'exécution.
J'ai donc à l'aise à la pensée que l'utilité des méthodes statiques qui n'ont pas besoin d'appeler d'autres classes ou des méthodes assez bien peut être statique. Mais les classes de service en général ne doit pas être statique. Cela vous permet de tirer parti de OOPs fonctionnalités comme primordial.
Également avoir un singleton instance de la classe nous permet de nous faire une classe un peu comme une classe statique toujours utiliser Oups concepts.
Disadvantage -> Static
Membres font partie de la classe et ainsi rester en mémoire jusqu'application se termine.et ne peut pas être toujours d'ordures collectées. À l'aide de l'excès de membres statiques parfois, prédit que vous ne parviennent pas à la conception de votre produit et en essayant de la cop de la statique /programmation procédurale. Il indique que la conception orientée objet est compromise.Cela peut résultat en mémoire sur l'écoulement.
Tout est une question de contexte. Certaines personnes ont déjà donné des exemples où statique est absolument préférable, comme lors de la rédaction de fonctions de l'utilitaire de avec pas concevable de l'état. Par exemple, si vous écrivez une collection de différents algorithmes de tri pour être utilisé sur les tableaux, ce qui rend votre méthode mais rien de statique confond tout simplement la situation. N'importe quel programmeur lecture de votre code, devraient se poser la question, pourquoi n'avez-vous PAS statique, et aurait qu'à regarder pour voir si vous faites quelque chose de dynamique de l'objet.
Cela étant dit, il ya beaucoup de gens qui ont écrit le code d'une certaine sorte, et insister sur le fait qu'ils ont certains des code, seulement pour trouver plus tard que elle ne l'est pas. Par exemple, vous souhaitez calculer les statistiques à une variable. Donc, vous écrivez:
Le premier élément de la mauvaise conception ici est que le programmeur a l'intention de simplement imprimer les résultats, plutôt que de façon générique les utiliser. L'incorporation d'e/S dans le calcul est terrible pour les réutiliser. Cependant, le problème suivant est que cet objectif général routine doit être le calcul de max, min, moyenne, variance, etc. et de le stocker quelque part. Où? Dans l'état d'un objet. Si c'était vraiment un one-off, vous pourrait-il faire en statique, mais bien sûr, vous allez trouver que vous voulez calculer la moyenne de deux choses différentes, et puis c'est très gentil si vous le pouvez il vous suffit d'instancier l'objet à plusieurs reprises.
De la réaction réflexe contre l'électricité statique est souvent la réaction des programmeurs à la bêtise de faire ce genre de chose de manière statique, car il est plus facile de dire de ne jamais le faire qu'en fait expliquer les cas qui sont ok, et qui sont stupides.
Noter que dans ce cas, je suis en train d'utiliser l'objet comme une sorte de but spécial les passer par référence, parce que Java est si odieux à cet égard. En C++, ce genre de chose aurait pu être une fonction, quel que soit leur état passé en tant que références. Mais même en C++, les mêmes règles s'appliquent, c'est juste que Java nous oblige à utiliser des objets de plus en raison de l'absence de passage par référence.
Autant que la performance va, la plus grande augmentation des performances de commutation à partir d'une méthode régulière est en fait d'éviter la dynamique polymorphes vérifier qui est la valeur par défaut en java, et qui en C++ est spécifié manuellement avec le virtuel.
Quand je l'ai essayé hier, il y avait un 3:1 l'avantage de l'appel d'une méthode finale sur une méthode régulière, mais pas perceptible pour l'appel de fonctions statiques sur final.
Notez que si vous appelez une méthode à partir d'un autre, le JIT est souvent assez intelligent pour insérer le code, auquel cas il n'est pas appel à tous, c'est pourquoi faire une déclaration au sujet de exactement combien vous épargnez est extrêmement dangereux. Tout ce que vous pouvez dire, c'est que lorsque le compilateur a pour appeler une fonction, il peut pas faire de mal si l'on peut appeler l'un comme statique ou finale, ce qui nécessite moins de calculs.
MySorter.Sort()
sur les deux tableaux montrent clairement que chaque tri action est indépendante. Si le code avait étéMySorter sorter = new MySorter(); sorter.sort(array1...); sorter.sort(array2...);
, il serait loin d'être évident de savoir si les actes en question étaient indépendants. On pourrait s'attendre à les trouver, mais si par exemple une méthode de tri sera probablement utilisé à plusieurs reprises sur les listes contenant des données similaires, c'est possible...sorter
instance devront veiller à ce que les opérations de tri serait vraiment indépendant. À l'aide d'une méthode statique rendrait leur indépendance de plus en plus apparente.Le principal problème que vous pouvez rencontrer est, vous ne serez pas en mesure de fournir une nouvelle mise en œuvre, si nécessaire.
Si vous avez encore des doutes ( si votre application peut changer dans le futur ou pas ), vous pouvez toujours utiliser une instance privée-dessous avec la mise en œuvre effective:
Si pour "certains" raison, vous avez besoin de changer la mise en œuvre de la classe vous pouvez offrir:
Mais peut être excessive dans certaines circonstances.
Afin d'appeler les méthodes statiques, vous n'avez pas besoin de créer des objets de la classe. La méthode est disponible immédiatement.
En supposant que la classe est déjà chargé. Sinon il y a un peu d'attente. 🙂
Je pense statique, comme un bon moyen de séparer le code fonctionnel de procédure/etat-réglage de code. Le code fonctionnel doit généralement pas d'extension et les modifications uniquement quand il y a des bugs.
Il y a aussi l'utilisation de statique, comme un accès à un mécanisme de contrôle--comme avec les singletons.
Non, en fait, la raison pour que le conseil est qu'il offre un avantage de performance. Les méthodes statiques ne peuvent être appelés avec moins de charge de sorte que toute méthode qui n'a pas besoin d'une référence à
this
doivent être statique.Non, il n'est pas d'inconvénients, mais plutôt de savoir quand vous n'êtes pas accès à tout les membres de l'instance dans la méthode, puis il n'y a pas de sens d'avoir comme une méthode d'instance. Il est bon de compétences en programmation pour l'avoir comme une méthode statique.
et en ajoutant à ce que vous n'avez pas à créer des instances pour accéder à ces méthodes, et ainsi économiser de la mémoire et de la collecte des ordures temps.
Un inconvénient est que si vos méthodes statiques sont d'ordre général et distribués dans les différentes classes, selon leur utilisation. Vous pourriez envisager de placer toutes les méthodes statiques qui sont en général dans une classe utilitaire.
Comme d'autres l'ont dit, il donne un léger avantage en termes de performance et est bien pratique. La seule exception est lorsque la méthode doit être une instance de la méthode de remplacement des fins, mais ceux-ci sont généralement faciles à reconnaître. Par exemple, si une classe fournit le comportement par défaut d'une méthode d'instance, ce qui se passe n'a pas besoin d'variables d'instance, qui clairement ne peut pas être statique.
En général:
Que vous devriez écrire vos logiciels pour profiter des interfaces et non pas mises en œuvre. Qui est-à-dire que "maintenant", vous ne utilisez pas une variable d'instance, mais dans l'avenir? Un exemple de codage d'interfaces...
Vous devriez être autorisé à swap mises en œuvre, en particulier pour les moqueries & test. Le printemps de l'injection de dépendances est assez agréable à cet égard. Juste injecter de la mise en œuvre du Printemps et bingo, vous avez assez bien "statique" (ainsi, singleton) méthode de...
Maintenant, ces types d'Api qui sont purement "utilitaire" dans le but (c'est à dire, Apache Commons Lang) sont l'exception ici parce que je crois que la plupart (si pas tous) des implémentations sont statiques. Dans cette situation, quelles sont les chances que vous voudrez jamais swap Apache Commons pour un autre API?
Spécifiquement:
Comment voulez-vous gérer de façon élégante la "staticness" de votre application lorsque vous ciblez, disons, une Websphere vs déploiement Tomcat? Je suis sûr qu'il y aurait une instance (aucun calembour prévu) de votre mise en œuvre diffèrent entre les deux...et en s'appuyant sur une méthode statique dans l'un de ces implémentations spécifiques pourrait être dangereux...
List myList = new ArrayList();
liens le code un peu inutilement à laArrayList();
type. Supposons que quelqu'un libère uneFasterArrayList
de mise en œuvre de ce qui est mieux queArrayList
dans tous les sens, sauf une: il ne peut pas être jeté àArrayList
. Trouver les endroits oùnew ArrayList()
vraiment besoin de créer un nouveauArrayList
(par rapport à une nouvelle mutableList
) pourrait être difficile. À l'aide d'un statique méthode de fabrique, au lieu d'un appel de constructeur n'importe où, là où le code n'a pas de soins si elle a effectivement eu unArrayList
serait plus facile de remplacer leFasterArrayList
.Il ne devrait pas être tous les inconvénients--il peut même y avoir un léger avantage en performances (bien qu'il ne serait pas mesurable) depuis la dynamique de recherche peuvent être évités.
Il est agréable de balise de fonctions comme des fonctions au lieu de les faire ressembler à des Méthodes--(et statique "Méthodes" SONT des fonctions, et non pas des méthodes--c'est en fait par définition).
En général une méthode statique est une mauvaise OO odeur de code--cela signifie probablement que votre OO modèle n'est pas entièrement intégré. Cela arrive tout le temps avec les bibliothèques qui ne peut pas connaître le code qui va l'utiliser, mais intégrées dans le non-bibliothèque de code statique méthodes devraient être examinés pour évaluer laquelle de ses paramètres, il est plus étroitement associé à la--il y a une bonne chance qu'il devrait être un membre de cette classe.
Si une méthode statique faut juste des valeurs autochtones, alors vous êtes probablement manque une poignée de classes, vous devez également garder en passant natif de variables ou de la bibliothèque des objets (comme des collections) à un minimum--contenant plutôt dans les classes avec la logique métier.
Je suppose que ce que je dis, c'est que si ce est vraiment un problème, vous pouvez revoir vos pratiques de modélisation--statique doit être si rare que ce n'est même pas un problème.