Cours BUT Info

Ch. 3 — Statique, final et énumérations

Attributs et méthodes de classe, constantes final, blocs d'initialisation statiques, boîtes à outils Arrays et Collections, et les énumérations Java : de vraies classes aux instances figées.

final : la constante

Le mot-clé final verrouille une valeur : une fois initialisée, elle ne peut plus être modifiée. Par convention, son identifiant s'écrit en majuscules. Une constante peut être initialisée à la déclaration — ou au constructeur, ce qui laisse la souplesse d'une valeur fixée par instance sans écrire de littéral « en dur » dans le code.

Le cours le montre sur un Disc qui calcule périmètre et aire avec un littéral 3.14 recopié dans chaque méthode : la première correction consiste à nommer la constante. Mais en déclarant private final double PI, chaque instance de Disc crée sa propre copie d'une valeur identique pour toutes — pas raisonnable. La suite logique est donc le niveau classe.

Les trois combinaisons à connaître

  • static final : la même constante pour toutes les instances — c'est le cas des wrappers (Integer.MAX_VALUE, Boolean.TRUE, Double.MIN_VALUE) ;
  • final sans static : une constante par instance, initialisée au constructeur ;
  • static sans final : une valeur commune à toutes les instances, modifiable.

static : le niveau classe

Un attribut de classe existe en un seul exemplaire, quel que soit le nombre d'instances — on y accède par le nom de la classe (Disc.PI), pas par une référence. Changer Disc.PI change d'un coup l'aire calculée par tous les disques. Le cours en donne l'usage canonique : le numéro automatique.

public class Order {
    private static final String ID_PREFIX = "order@";
    private static int counter = 1;
    private Person client;
    private String id;

    public Order(Person cli) {
        this.client = cli;
        this.id = Order.ID_PREFIX + Order.counter++;
    }
}

Trois commandes créées successivement reçoivent order@1, order@2, order@3 : le compteur est une mémoire partagée entre les instances. Quand l'initialisation exige un traitement, elle quitte le constructeur pour un bloc statique, exécuté une seule fois au chargement de la classe :

static final int[] VALUES;
static {
    VALUES = new int[SIZE];
    for (int i = 0; i < VALUES.length; i++) { VALUES[i] = i; }
}

Les méthodes de classe s'invoquent sans instance (StaticExample.staticMethod()) — main en est le cas particulier, puisqu'elle s'exécute avant tout objet. Le support insiste : n'utilisez des attributs ou méthodes de classe que quand c'est indispensable.

Les boîtes à outils : Arrays et Collections

Une classe « boîte à outils » regroupe des traitements qui ne concernent aucune instance en particulier : presque toutes ses méthodes sont statiques. java.util.Arrays facilite la manipulation des tableaux — affichage, remplissage, test d'égalité, recherche, tri :

int[] tab = {1, 5, 2, 0, 7, 3};
Arrays.toString(tab);            // "[1, 5, 2, 0, 7, 3]" — finie la boucle d'affichage
Arrays.fill(tab, 10);            // remplissage forcé à une même valeur
int[] copy = Arrays.copyOf(tab, 10); // copie tronquée ou complétée par des zéros
Arrays.equals(tab, copy);        // égalité contenu à contenu (pas de == !)
Arrays.sort(tab, 3, tab.length); // tri complet ou partiel
Arrays.binarySearch(tab, 7);     // recherche dichotomique

Pour les tableaux de tableaux, toString et equals ne voient que des références ([[I@4aa298b7, ...], false) : il faut les versions profondes deepToString et deepEquals.

binarySearch exige un tableau trié

La recherche dichotomique suppose un tableau ordonné — sur un tableau non trié, le résultat n'a pas de sens. Une valeur absente renvoie un entier négatif (-7 sur l'exemple du cours) : à lire comme « non trouvé », pas comme une position.

L'enum : une classe aux instances figées

Un type énuméré est une classe avec un nombre prédéfini et fixe d'instances — les valeurs sont des objets, instances de la classe créée :

public enum Season { SPRING, SUMMER, FALL, WINTER }
Season s = Season.SUMMER;

Chaque enum fournit d'office : name() (le nom exact de la constante), ordinal() (sa position dans la déclaration, à partir de 0) et, côté classe, valueOf(String) et values(). Le cours démonte le code généré par le compilateur pour bien comprendre : une classe à constructeur privé, dont les valeurs sont des attributs static final instanciés une fois pour toutes — impossible d'en créer d'autres. L'enum reste une vraie classe, que l'on peut enrichir : attributs, méthodes, constructeurs paramétrés (à condition qu'ils restent privés).

public enum Day {
    MONDAY(true), TUESDAY(true), WEDNESDAY(true), THURSDAY(true),
    FRIDAY(true), SATURDAY(false), SUNDAY(false);
    private final boolean WORKING;
    private Day(boolean value) { this.WORKING = value; }
    public boolean isAWorkingDay() { return this.WORKING; }
}

Les combinaisons d'ordinal() et values() font de petites mécaniques élégantes — passer à la saison suivante : Season.values()[(index + 1) % Season.values().length]. En UML : les membres static sont soulignés, les constantes final en majuscules, et l'enum porte le stéréotype «enum».

Quand choisir une enum ?

Dès que l'ensemble de valeurs est fermé — saisons, statuts, couleurs de carte : le compilateur vérifie l'exhaustivité des traitements, l'autocomplétion liste les valeurs, et une faute de frappe dans une chaîne devient impossible.

A retenir

  • final interdit la réaffectation ; static place le membre au niveau de la classe ;
  • numéro automatique et bloc statique : les deux idiomes static du cours ;
  • Arrays/Collections : des boîtes à outils de méthodes statiques ;
  • une enum est une classe enrichissable, à instances figées dès la déclaration.


coursOO_03.pdf

R2.01 · Cours 3 — Attributs, méthodes et classes statiques · 32 diapositives

Consultation seule — téléchargement désactivé

Chargement du document…

Dernière mise à jour le

Sur cette page