Un guide sur le mot-clé statique en Java

1. Introduction

Dans cet article, nous explorerons en détail le mot-clé static du langage Java. Nous verrons comment appliquer le mot-clé statique aux variables, méthodes, blocs, classes imbriquées et quelle différence cela fait.

2. L'anatomie du mot-clé statique

Dans le langage de programmation Java, le mot-clé static indique que le membre particulier appartient à un type lui-même, plutôt qu'à une instance de ce type .

Cela signifie qu'une seule instance de ce membre statique est créée, qui est partagée entre toutes les instances de la classe.

Le mot-clé peut être appliqué à des variables, des méthodes, des blocs et des classes imbriquées.

3. Les champs statiques (ou variables de classe)

En Java, si un champ est déclaré statique , alors exactement une seule copie de ce champ est créée et partagée entre toutes les instances de cette classe . Peu importe le nombre de fois que nous initialisons une classe; il n'y aura toujours qu'une seule copie du champ statique lui appartenant. La valeur de ce champ statique sera partagée entre tous les objets de l'un ou l'autre de n'importe quelle classe différente.

Du point de vue de la mémoire, les variables statiques vont dans un pool particulier de la mémoire JVM appelé Metaspace (avant Java 8, ce pool s'appelait Permanent Generation ou PermGen, qui a été complètement supprimé et remplacé par Metaspace).

3.1. Exemple du champ statique

Supposons que nous ayons une classe Car avec plusieurs attributs (variables d'instance) . Chaque fois que de nouveaux objets sont initialisés à partir de ce modèle de voiture , chaque nouvel objet aura sa copie distincte de ces variables d'instance.

Cependant, supposons que nous recherchions une variable contenant le décompte du nombre d' objets Car initialisés et partagés entre toutes les instances afin qu'ils puissent y accéder et l'incrémenter lors de leur initialisation.

C'est là que les variables statiques entrent en jeu:

public class Car { private String name; private String engine; public static int numberOfCars; public Car(String name, String engine) { this.name = name; this.engine = engine; numberOfCars++; } // getters and setters }

Désormais, pour chaque objet de cette classe initialisé, la même copie de la variable numberOfCars est incrémentée. Donc, dans ce cas, les affirmations suivantes seront vraies:

@Test public void whenNumberOfCarObjectsInitialized_thenStaticCounterIncreases() { new Car("Jaguar", "V8"); new Car("Bugatti", "W16"); assertEquals(2, Car.numberOfCars); }

3.2. Raisons impérieuses d'utiliser des champs statiques

  • Lorsque la valeur de la variable est indépendante des objets
  • Lorsque la valeur est censée être partagée entre tous les objets

3.3. Points clés à retenir

  • Étant donné que les variables statiques appartiennent à une classe, elles sont accessibles directement à l'aide du nom de classe et n'ont pas besoin de référence d'objet
  • les variables statiques ne peuvent être déclarées qu'au niveau de la classe
  • les champs statiques sont accessibles sans initialisation d'objet
  • Bien que nous puissions accéder aux champs statiques en utilisant une référence d'objet (comme ford.numberOfCars ++ ), nous devons nous abstenir de l'utiliser car dans ce cas, il devient difficile de déterminer s'il s'agit d'une variable d'instance ou d'une variable de classe; au lieu de cela, nous devrions toujours faire référence aux variables statiques en utilisant le nom de classe (par exemple, dans ce cas, Car.numberOfCars ++ )

4. Les méthodes statiques (ou méthodes de classe)

À l'instar des champs statiques , les méthodes statiques appartiennent également à une classe au lieu de l'objet, et peuvent donc être appelées sans créer l'objet de la classe dans laquelle elles résident. Ils sont destinés à être utilisés sans créer d'objets de la classe.

4.1. Exemple de méthode statique

Les méthodes statiques sont généralement utilisées pour effectuer une opération qui ne dépend pas de la création de l'instance.

S'il existe un code censé être partagé entre toutes les instances de cette classe, écrivez ce code dans une méthode statique :

public static void setNumberOfCars(int numberOfCars) { Car.numberOfCars = numberOfCars; }

Les méthodes statiques sont également largement utilisées pour créer des classes utilitaires ou d'assistance afin qu'elles puissent être obtenues sans créer un nouvel objet de ces classes.

Jetez simplement un œil aux classes d'utilitaires Collections ou Math de JDK, StringUtils d'Apache ou CollectionUtils du framework Spring et notez que toutes les méthodes sont statiques .

4.2. Raisons impérieuses d'utiliser des méthodes statiques

  • Pour accéder / manipuler des variables statiques et d'autres méthodes statiques qui ne dépendent pas d'objets
  • les méthodes statiques sont largement utilisées dans les classes utilitaires et auxiliaires

4.3. Points clés à retenir

  • les méthodes statiques en Java sont résolues au moment de la compilation. Étant donné que la substitution de méthode fait partie du polymorphisme d'exécution, les méthodes statiques ne peuvent donc pas être remplacées
  • les méthodes abstraites ne peuvent pas être statiques
  • les méthodes statiques ne peuvent pas utiliser ce ou des super mots clés
  • Les combinaisons suivantes de l'instance, des méthodes de classe et des variables sont valides:
    1. Les méthodes d'instance peuvent accéder directement aux méthodes d'instance et aux variables d'instance
    2. Les méthodes d'instance peuvent également accès statiques variables et statiques méthodes directement
    3. les méthodes statiques peuvent accéder à toutes les variables statiques et à d'autres méthodes statiques
    4. les méthodes statiques ne peuvent pas accéder directement aux variables d'instance et aux méthodes d'instance ; ils ont besoin d'une référence d'objet pour le faire

5. Un bloc statique

Un bloc statique est utilisé pour initialiser les variables statiques . Bien que les variables statiques puissent être initialisées directement lors de la déclaration, il existe des situations où nous devons effectuer le traitement multiligne.

Dans de tels cas, les blocs statiques sont utiles.

Si les variables statiques nécessitent une logique multi-instructions supplémentaire lors de l'initialisation, un bloc statique peut être utilisé.

5.1. L' exemple de bloc statique

Supposons que nous voulions initialiser un objet de liste avec des valeurs prédéfinies.

Cela devient facile avec les blocs statiques :

public class StaticBlockDemo { public static List ranks = new LinkedList(); static { ranks.add("Lieutenant"); ranks.add("Captain"); ranks.add("Major"); } static { ranks.add("Colonel"); ranks.add("General"); } }

Dans cet exemple, il ne serait pas possible d'initialiser l' objet List avec toutes les valeurs initiales ainsi que la déclaration; et c'est pourquoi nous avons utilisé le bloc statique ici.

5.2. Raisons convaincantes d'utiliser des blocs statiques

  • Si l'initialisation de variables statiques nécessite une logique supplémentaire à l'exception de l'affectation
  • If the initialization of static variables is error-prone and requires exception handling

5.3. Key Points to Remember

  • A class can have multiple static blocks
  • static fields and static blocks are resolved and executed in the same order as they are present in the class

6. A static Class

Java programming language allows us to create a class within a class. It provides a compelling way of grouping elements that are only going to be used in one place, this helps to keep our code more organized and readable.

The nested class architecture is divided into two:

  • nested classes that are declared static are called static nested classes whereas,
  • nested classes that are non-static are called inner classes

The main difference between these two is that the inner classes have access to all member of the enclosing class (including private), whereas the static nested classes only have access to static members of the outer class.

In fact, static nested classes behaved exactly like any other top-level class but enclosed in the only class which will access it, to provide better packaging convenience.

6.1. Example of static Class

The most widely used approach to create singleton objects is through static nested class is it doesn't require any synchronization and is easy to learn and implement:

public class Singleton { private Singleton() {} private static class SingletonHolder { public static final Singleton instance = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.instance; } }

6.2. Compelling Reasons to Use a static Inner Class

  • Grouping classes that will be used only in one place increases encapsulation
  • The code is brought closer to the place that will be only one to use it; this increases readability and code is more maintainable
  • If nested class doesn't require any access to it's enclosing class instance members, then it's better to declare it as static because this way, it won't be coupled to the outer class and hence will be more optimal as they won't require any heap or stack memory

6.3. Key Points to Remember

  • static nested classes do not have access to any instance members of the enclosing outer class; it can only access them through an object's reference
  • les classes imbriquées statiques peuvent accéder à tous les membres statiques de la classe englobante, y compris les classes privées
  • La spécification de programmation Java ne nous permet pas de déclarer la classe de premier niveau comme statique ; seules les classes au sein des classes (classes imbriquées) peuvent être rendues statiques

7. Conclusion

Dans cet article, nous avons vu le mot-clé static en action. Nous lisons également les raisons et les avantages de l'utilisation de champs statiques, de méthodes statiques, de blocs statiques et de classes internes statiques.

Comme toujours, nous pouvons trouver le code complet sur GitHub.