10
votes

Java Méthodes statiques Avantages et inconvénients

Je n'ai pas utilisé beaucoup de méthodes statiques avant, mais je suis récemment récemment eu à utiliser davantage d'entre eux. Par exemple, si je veux définir un drapeau booléen dans une classe ou accéder à un sans avoir besoin de passer l'objet réel à travers des classes.

Par exemple: P>

public class MainLoop
{
    private static volatile boolean finished = false;

    public void run()
    {
        while ( !finished )
        {
            // Do stuff
        }

    }
    // Can be used to shut the application down from other classes, without having the actual object
    public static void endApplication()
    {
        MainLoop.finished = true;
    }

}


4 commentaires

La variable terminée est vraiment "globale" à la classe. Java n'a pas vraiment de variables "globales" (à tout).


@Hasslarn: Votre code est cassé (et je suis un peu surpris que, après quatre réponses, personne ne l'a mentionné): Il y a une garantie absolument zéro que lorsqu'un autre thread doit appeler endapplication () la valeur doit être Lisez comme true par le fil exécutant la méthode exécution () . Vous DO utiliser un mécanisme de synchronisation ici, comme par exemple en déclarant fini comme volatile .


@HassLarn: J'ai édité votre question et corrigé votre code (pas que l'utilisation de statique de cette manière est propre ou tout) en ajoutant volatile à votre drapeau booléen.


S'applaudonne à vous pour le remarquer, a rendu un peu fait l'exemple sur la mouche pour faire mon point :)


4 Réponses :


5
votes

Est-ce quelque chose que je devrais éviter?

En général, oui. Les statiques représentent l'état global . L'État mondial est difficile à raisonner, difficile à tester de manière isolée et présente généralement des exigences plus élevées de sécurité de thread-sécurité.

Si je veux tester ce qui arrive à un objet dans un certain état, je peux simplement créer l'objet, le mettre dans cet état, effectuer mes tests et la laisser obtenir des ordures collectées. < / p>

Si je veux tester ce qui arrive à l'état global , je dois m'assurer que je réinitialise tout à la fin de mon test (ou éventuellement au début de chaque test). Les tests vont maintenant interférer les uns avec les autres si je ne fais pas attention à ce que ce soit.

Bien sûr, si la méthode statique n'a pas besoin d'affecter aucun état - c'est-à-dire si c'est pur - alors il devient un peu mieux. À ce stade, tout ce que vous perdez est la capacité de remplacer cette mise en œuvre de la méthode, par ex. Lorsque vous testez quelque chose qui l'appelle.


0 commentaires

7
votes

Oui, passer des objets autour est meilleur. L'utilisation d'un singleton ou des méthodes statiques rend la programmation OO comme une programmation procédurale. Un singleton est un peu meilleur car vous pouvez au moins que vous puissiez mettre en œuvre des interfaces ou étendre une classe abstraite, mais c'est généralement une odeur de conception.

et mélange des méthodes d'instance avec des variables statiques telles que vous faites est encore plus confuse: vous pouvez avoir plusieurs objets en boucle, mais vous les arrêtez tous immédiatement parce qu'ils sont tous arrêtés lorsqu'une variable statique change.


0 commentaires

2
votes

En général, en faisant fini statique comme si vous créez une situation dans laquelle il ne peut s'agir que d'une instance de votre Mainloop exécutant de classe exécuter à n'importe quel moment. S'il y a plus d'une instance, régler fini finira tous - pas ce qui est habituellement souhaité.

Cependant, dans ce scénario particulier , où vous souhaitez "mettre fin à l'application", ce qui signifie probablement que vous souhaitez terminer toutes les instances de Mainloop , l'approche peut être justifiée.

Toutefois, le nombre de situations dans lesquelles cette approche peut être méritée sont peu nombreuses, et une manière "plus propre" de gérer ce scénario serait de conserver une liste des instances statique et de travailler via la liste, Réglage de la variable d'instance terminé dans chaque instance. Cela vous permet également de mettre fin à des instances individuelles, vous donne un nombre naturel d'instances existantes, etc.


1 commentaires

Oui, moi, moi-même dans ce scénario, croyez que c'est justifié, mais cela pourrait faire une expansion de la même base que vous et tous les autres impliquent. Merci pour l'exemple de contournement



8
votes

Un problème d'utilisation d'une variable statique dans ce cas est que si vous créez deux (ou plus) instances de Mainloop, code d'écriture qui ressemble à une fermeture d'une seule des instances, fera effectivement arrêter les deux:

MainLoop mainLoop1 = new MainLoop();
MainLoop mainLoop2 = new MainLoop();

new Thread(mainLoop1).start();
new Thread(mainLoop2).start();

mainLoop1.finished = true; // static variable also shuts down mainLoop2 


0 commentaires