Quand ne pas utiliser le mot-clé statique en Java?

quand est-il considéré comme une mauvaise pratique d'utiliser le mot-clé statique en Java sur les signatures de méthode? Si une méthode exécute une fonction basée sur certains arguments, et ne nécessite pas l'accès à des champs qui ne sont pas statiques, alors ne voudriez-vous pas toujours que ces types de méthodes soient statiques?

26
demandé sur Jonik 2009-11-20 00:32:14

9 réponses

une des raisons pour lesquelles vous peut ne voulez pas qu'il soit statique est de permettre qu'il soit dépassé dans une sous-classe. En d'autres termes, le comportement peut ne pas dépendre sur les données à l'intérieur de l'objet, mais sur le type exact de l'objet. Par exemple, vous pourriez avoir un type de collection générale, avec une propriété isReadOnly qui retournerait false dans des collections toujours-mutables, true dans des collections toujours-immuables, et dépend de variables d'instance dans d'autres.

cependant, cela est assez rare dans mon expérience - et devrait généralement être explicitement spécifié pour la clarté. Normalement, je ferais une méthode qui ne dépend d'aucun état de l'objet statique.

31
répondu Jon Skeet 2009-11-19 21:46:44

deux des plus grands maux que vous ne rencontrerez jamais dans les applications Java à grande échelle sont

  • méthodes Statiques, à l'exception de ceux qui sont de pures fonctions*
  • champs statiques modifiables

ceux-ci ruinent la modularité, l'extensibilité et la testabilité de votre code à un degré que je me rends compte que je ne peux pas espérer vous convaincre de dans ce temps et espace limité.

*a " pur function" est toute méthode qui ne modifie aucun état et dont le résultat ne dépend que des paramètres qui lui sont fournis. Ainsi, par exemple, toute fonction qui exécute des E/S (directement ou indirectement) n'est pas une fonction pure, mais des mathématiques.sqrt(), bien sûr, est.

plus de blahblah sur les fonctions pures (SELF-link) et pourquoi vous voulez vous y tenir.

je vous encourage fortement à favoriser le style de programmation" injection de dépendances", éventuellement pris en charge par un framework comme Spring ou Guice (disclaimer: je suis co-auteur de cette dernière). Si vous faites ce droit, vous aurez essentiellement jamais besoin de l'état statique mutable ou des méthodes statiques non-pures.

42
répondu Kevin Bourrillion 2009-11-19 21:40:52

en général, je préfère les méthodes d'instance pour les raisons suivantes:

  1. méthodes statiques faire des essais dur parce qu'ils ne peuvent pas être remplacés,
  2. Les méthodes statiques
  3. sont davantage axées sur les procédures.

à mon avis, les méthodes statiques sont acceptables pour les classes d'utilité (comme StringUtils ) mais je préfère éviter de les utiliser autant que possible.

23
répondu Pascal Thivent 2009-11-19 23:00:04

ce que vous dites est en quelque sorte vrai, mais que se passe-t-il quand vous voulez Outrepasser le comportement de cette méthode dans une classe dérivée? Si c'est statique, tu ne peux pas faire ça.

à titre d'exemple, considérons la classe de type DAO suivante:

class CustomerDAO {
    public void CreateCustomer( Connection dbConn, Customer c ) {
       // Some implementation, created a prepared statement, inserts the customer record.
    }

    public Customer GetCustomerByID( Connection dbConn, int customerId ) {
       // Implementation
    }
}

maintenant, aucune de ces méthodes ne nécessite un "État". Tout ce dont ils ont besoin est passé en paramètres. Donc ils pourraient facilement être statiques. Maintenant, l'exigence vient le long que vous devez soutenir un différent base de données (disons Oracle)

puisque ces méthodes ne sont pas statiques, vous pouvez juste créer une nouvelle classe DAO:

class OracleCustomerDAO : CustomerDAO {
    public void CreateCustomer( Connection dbConn, Customer c ) {
        // Oracle specific implementation here.
    }

    public Customer GetCustomerByID( Connection dbConn, int customerId ) {
        // Oracle specific implementation here.
    }
}

Cette nouvelle classe peut maintenant être utilisé à la place de l'ancien. Si vous utilisez dependancy injection, il pourrait même ne pas exiger un changement de code du tout.

mais si nous avions rendu ces méthodes statiques, cela rendrait les choses beaucoup plus compliquées car nous ne pouvons pas simplement passer outre les méthodes statiques dans une nouvelle classe.

4
répondu Eric Petroelje 2009-11-19 21:46:23

méthodes statiques sont généralement écrits à deux fins. Le premier objectif est d'avoir une sorte de méthode d'utilité globale, similaire à la sorte de fonctionnalité trouvée dans java.util.Collections . Ces méthodes statiques sont généralement inoffensifs. Le second objectif est de contrôler l'instanciation d'objet et de limiter l'accès aux ressources (telles que les connexions de bases de données) via divers modèles de conception tels que singletons et usines . Celles-ci peuvent, si elles sont mal mises en œuvre, entraîner des problèmes.

pour moi, il y a deux inconvénients à utiliser des méthodes statiques:

  1. ils rendent le code moins modulaire et plus difficile à tester / étendre. La plupart des réponses déjà donc je ne vais pas en plus.
  2. les méthodes statiques ont tendance à produire une forme d'état global, qui est souvent la cause de bogues insidieux. Cela peut se produire dans le code mal écrit qui est écrit pour le deuxième objectif décrit ci-dessus. Permettez-moi de préciser.

par exemple, envisagez un projet qui nécessite l'enregistrement de certains événements dans une base de données, et qui dépend de la connexion à la base de données pour d'autres États également. Supposons que normalement, la connexion à la base de données est initialisée en premier, puis que le cadre de journalisation est configuré pour écrire certains événements de journalisation dans la base de données. Supposons maintenant que les développeurs décident de passer d'un cadre de base de données écrit à la main à un cadre de base de données existant, comme hibernation.

cependant, ce framework est susceptible d'avoir sa propre configuration de journalisation - et s'il se trouve qu'il utilise le même framework de journalisation que le vôtre, alors il y a de bonnes chances qu'il y ait différents conflits entre les configurations. Soudainement, le passage à un cadre de base de données différent entraîne des erreurs et des échecs dans différentes parties du système qui ne semblent pas liées. La raison de ces échecs peuvent se produire est parce que la configuration de journalisation maintient l'état global auquel on accède par des méthodes et variables statiques, et diverses propriétés de configuration peuvent être supplantées par différentes parties du système.

pour échapper à ces problèmes, les développeurs doivent éviter de stocker n'importe quel état via des méthodes et variables statiques. Au lieu de cela, ils devraient construire des API propres qui permettent aux utilisateurs de gérer et d'isoler l'état selon les besoins. BerkeleyDB est un bon exemple ici, encapsulant état via un objet environnement au lieu de via des appels statiques.

1
répondu toluju 2009-11-19 23:30:30

c'est ça. En effet, vous devez contorsionner ce qui pourrait être un design raisonnable (pour avoir certaines fonctions non associées à une classe) en termes Java. C'est pour cela que vous voyez des classes polyvalentes comme FredsSwingUtils et YetAnotherIOUtils.

0
répondu Jonathan Feinberg 2009-11-19 21:35:59

lorsque vous voulez utiliser une classe membre, indépendamment de tout objet de cette classe,il doit être déclarée statique.

Si elle est déclarée statique, il peut être accédé sans une instance d'un objet de la classe. Un membre statique est partagé par tous les objets de cette classe.

0
répondu Gnark 2009-11-19 21:39:11

un ennui supplémentaire sur les méthodes statiques: il n'y a pas de moyen facile de passer une référence à une telle fonction autour sans créer une classe enveloppante autour. Par exemple: - quelque chose comme:

FunctorInterface f = new FunctorInterface() { public int calc( int x) { return MyClass.calc( x); } };

je déteste ce genre de bricolage java. Peut-être qu'une version ultérieure de java aura des délégués ou un pointeur de fonction similaire / mécanisme de type procédural?

une plainte mineure, mais une chose de plus à pas comme environ gratuit fonctions statiques, méthodes.

0
répondu Roboprog 2009-11-19 22:06:20

deux questions ici 1) une méthode statique qui crée des objets reste chargée en mémoire quand on y accède la première fois? N'est-ce pas (rester chargé en mémoire) un inconvénient? 2) L'un des avantages de L'utilisation de Java est sa fonction de collecte des ordures - n'ignorons-nous pas cela lorsque nous utilisons des méthodes statiques?

0
répondu Subramanian 2010-03-09 06:41:04