Menu

Membres statiques en Java : champs et méthodes static

Ce que fait le mot-clé static en Java, comment les champs et méthodes static appartiennent à la classe plutôt qu'aux objets, et quand recourir aux blocs static et aux constantes.

Cette page contient des éditeurs exécutables - modifiez, exécutez et voyez la sortie instantanément.

Appartenir à la classe, pas à l'objet

La plupart des champs et méthodes que vous avez écrits jusqu'ici appartiennent à des objets : chaque fois que vous appelez new, chaque instance reçoit sa propre copie des champs, et les méthodes s'exécutent sur l'état de cet objet précis. Le mot-clé static renverse cela. Un membre static appartient à la classe elle-même - il en existe une seule copie, partagée par toutes les instances, et elle existe que vous créiez un objet ou non.

Cette seule distinction explique les champs static, les méthodes static, les constantes, et même pourquoi main est toujours static.

Un champ static partagé

Un champ non statique donne à chaque objet son propre emplacement. Un champ static donne à la classe un emplacement unique que tous partagent. L'exemple classique est un compteur qui suit combien d'objets ont été créés :

Remarquez que vous lisez le compteur sous la forme User.count - via le nom de la classe, car la valeur n'appartient à aucun User en particulier. Chaque name, en revanche, vit à l'intérieur de son propre objet. Modifiez count via n'importe quelle instance et toutes les instances voient la nouvelle valeur, car il n'en existe qu'une seule.

Méthodes static

Une méthode static appartient elle aussi à la classe, vous l'appelez donc sur la classe sans objet :

C'est exactement le schéma qui sous-tend la bibliothèque standard : Math.max, Integer.parseInt, Arrays.sort et List.of sont tous static - un comportement utilitaire qui n'a besoin d'aucun objet pour fonctionner. Recourez à une méthode static quand le travail dépend uniquement de ses arguments, et non de l'état propre à un objet.

Le grand piège : static ne peut pas voir instance

Une méthode static s'exécute sans aucun objet, il n'y a donc pas de this. Cela signifie qu'elle ne peut pas accéder aux champs d'instance ni appeler directement des méthodes d'instance - il n'y a aucun objet précis depuis lequel les lire. C'est l'erreur de débutant la plus courante avec static :

class Account {
    int balance = 100;          // champ d'instance

    static int show() {
        return balance;         // ERREUR DE COMPILATION : le champ non statique 'balance'
    }                           // ne peut pas être référencé depuis un contexte statique
}

La solution consiste soit à faire de la méthode une méthode d'instance (retirer static, pour qu'elle dispose d'un this), soit à passer l'objet explicitement :

Le sens inverse ne pose aucun problème : une méthode d'instance peut lire librement les champs static et appeler les méthodes static, car les données partagées au niveau de la classe existent toujours.

Les constantes avec static final

Combinez static avec final et vous obtenez une constante : une valeur unique partagée qui ne peut jamais changer. Par convention, on les nomme en UPPER_SNAKE_CASE :

static final est la manière idiomatique d'exprimer « une valeur fixe qui appartient au type » - des choses comme Integer.MAX_VALUE ou Math.PI dans la bibliothèque standard. La rendre static signifie que vous ne gaspillez pas une copie par objet ; la rendre final signifie que personne ne peut la réaffecter.

Blocs d'initialisation static

Un champ static simple peut être initialisé en ligne. Quand la mise en place nécessite une vraie logique - construire une table de correspondance, lire une configuration - utilisez un bloc static. Il s'exécute une seule fois, au premier chargement de la classe, avant qu'aucun objet n'existe :

Le bloc se déclenche une seule fois, quel que soit le nombre de fois où vous utilisez la classe, ce qui en fait le bon endroit pour une mise en place unique, valable pour toute la classe.

Quand utiliser static

Une règle empirique rapide :

  • N'utilisez un champ static que pour des données réellement partagées par toutes les instances - un compteur, un cache, une constante. Si deux objets pouvaient raisonnablement contenir des valeurs différentes, cela devrait plutôt être un champ d'instance.
  • Utilisez une méthode static quand le résultat dépend uniquement des arguments, et non de l'état d'un objet (fonctions utilitaires pures).
  • Par défaut, privilégiez les membres d'instance. Abuser de static transforme silencieusement votre programme en un tas d'état global, difficile à tester et à raisonner. static est l'exception, pas le point de départ.

Suite : les Enums

Une constante static final convient pour une seule valeur fixe, mais lorsque vous avez un ensemble petit et fixe de valeurs liées - directions, jours de la semaine, statuts de commande - Java propose un type conçu spécialement, plus sûr et plus expressif que des constantes éparpillées. C'est l'enum, et c'est la page suivante.

Questions fréquentes

Que signifie static en Java ?

static signifie qu'un champ ou une méthode appartient à la classe elle-même, et non à un objet particulier. Il existe exactement une seule copie d'un champ static partagée par toutes les instances, et une méthode static s'appelle sur la classe (Math.max(...)) sans avoir besoin d'un objet. À l'inverse, les membres non statiques (d'instance) obtiennent une nouvelle copie pour chaque objet.

Quelle est la différence entre variables static et variables d'instance en Java ?

Une variable d'instance a une valeur par objet - deux objets peuvent contenir des valeurs différentes. Une variable static possède une valeur unique partagée par tous les objets de la classe ; la modifier via un objet (ou via le nom de la classe) est donc visible par tous les autres. Utilisez des champs d'instance pour l'état propre à chaque objet et des champs static pour des données réellement globales à la classe, comme un compteur ou une constante.

Pourquoi la méthode main est-elle static en Java ?

La JVM doit appeler main avant qu'aucun objet de votre classe n'existe. Comme une méthode static appartient à la classe et non à une instance, l'environnement d'exécution peut invoquer directement Main.main(args) sans construire d'abord un Main. C'est pourquoi la signature est toujours public static void main(String[] args).

Coddy programming languages illustration

Apprendre à coder avec Coddy

COMMENCER