CodeGym /Cours /JAVA 25 SELF /Classes locales : déclaration à l'intérieur des méthodes

Classes locales : déclaration à l'intérieur des méthodes

JAVA 25 SELF
Niveau 16 , Leçon 3
Disponible

1. Classe locale

Une classe locale est une classe déclarée à l’intérieur d’une méthode (ou même d’un bloc de code, par exemple dans une boucle ou un bloc if). Elle est visible et accessible uniquement dans cette méthode ; en dehors — c’est comme si elle n’existait pas. Contrairement aux classes anonymes, une classe locale a un nom (même simple), peut contenir plusieurs méthodes et même des champs.

Par analogie — imaginez que vous préparez un plat complexe selon une recette. À l’une des étapes, vous devez préparer une sauce spéciale, utilisée uniquement dans cette recette et nulle part ailleurs. Au lieu de publier un livre de recettes séparé pour une seule sauce, vous décrivez simplement sa préparation directement dans la recette principale. Une classe locale fonctionne de la même manière — c’est « une recette dans la recette », nécessaire uniquement dans une méthode précise.

Exemple de déclaration d’une classe locale

public class Outer {
    void someMethod() {
        class Local {
            void print() {
                System.out.println("Hello from Local!");
            }
        }
        Local local = new Local();
        local.print();
    }
}

Ici, la classe Local est déclarée à l’intérieur de la méthode someMethod de la classe Outer. Elle n’existe que dans cette méthode et n’est pas visible de l’extérieur.

Syntaxe des classes locales

La déclaration d’une classe locale ressemble à une déclaration de classe ordinaire, sauf qu’elle a lieu à l’intérieur d’une méthode :

void myMethod() {
    class MyLocalClass {
        void doSomething() {
            System.out.println("La classe locale fonctionne!");
        }
    }

    MyLocalClass obj = new MyLocalClass();
    obj.doSomething();
}

Particularités de la syntaxe :

  • Une classe locale peut être déclarée dans n’importe quelle méthode, constructeur ou même bloc d’initialisation.
  • Le nom d’une classe locale est obligatoire (contrairement aux classes anonymes).
  • Une classe locale ne peut pas être déclarée avec des modificateurs d’accès (public, private, protected) ni avec le modificateur static.
  • Une classe locale peut implémenter des interfaces ou hériter d’autres classes.

Comparaison des types de classes :

public class Example {
// 1. Classe ordinaire (dans un fichier distinct)
// class RegularClass { ... }

    // 2. Classe interne (dans une classe)
    class InnerClass { }
    
    // 3. Classe imbriquée statique (dans une classe)
    static class NestedClass { }
    
    void method() {
        // 4. Classe locale (dans une méthode)
        class LocalClass { }
        
        // 5. Classe anonyme (dans une méthode, sans nom)
        Object obj = new Object() { };
    }
}

Classe locale = une classe nommée réservée à cette méthode !

2. Particularités des classes locales

Accès aux variables de la méthode

Une classe locale peut accéder :

  • Aux champs de la classe englobante (même s’ils sont private).
  • Uniquement aux variables final ou effectively final de la méthode environnante.

Qu’est-ce que « effectively final » ?
C’est une variable dont la valeur ne change pas après son initialisation. Par exemple :

void foo() {
    int x = 5; // effectively final
    class L { void print() { System.out.println(x); } }
}

Si, plus tard, vous écriviez x = 10;, le compilateur se plaindrait.

Pourquoi ?

Cela tient à la manière dont Java implémente les classes locales « sous le capot » : les variables de la méthode sont en fait copiées dans la classe locale, et non stockées par référence. Si la variable pouvait changer, la classe locale pourrait travailler avec une copie obsolète — et c’est la voie vers des bugs et des maux de tête.

Exemple d’accès aux variables

public class Outer {
    private String secret = "secret!";

    void revealSecret() {
        String greeting = "Bonjour,"; // effectively final

        class Revealer {
            void printSecret() {
                System.out.println(greeting + " " + secret);
            }
        }

        Revealer revealer = new Revealer();
        revealer.printSecret();
    }
}

3. Utilisation des classes locales : pourquoi et quand ?

Les classes locales ne sont pas un outil du quotidien, mais elles rendent parfois le code plus clair et plus compact. Voici quand il vaut la peine de les utiliser :

  • Logique auxiliaire, spécifique à une seule méthode.
    Par exemple, si vous devez implémenter dans une méthode un tri complexe, un filtrage ou une structure de données temporaire.
  • Encapsulation, pour ne pas « polluer » la classe avec des types superflus.
    Si une classe n’est utile qu’à un seul endroit, pourquoi la rendre visible dans toute la classe ou le package ?
  • Mise en œuvre de patrons de conception, lorsque des objets auxiliaires ne sont nécessaires que localement.

Exemple : trier avec une classe locale

Supposons que vous ayez une liste de noms et que vous souhaitiez les trier par longueur. Vous pouvez créer une classe locale comparatrice :

import java.util.*;

public class NameSorter {
    public void sortNames(List<String> names) {
        class LengthComparator implements Comparator<String> {
            @Override
            public int compare(String a, String b) {
                return Integer.compare(a.length(), b.length());
            }
        }
        Collections.sort(names, new LengthComparator());
    }
}

Exemple : structure temporaire

Parfois, vous devez créer une structure auxiliaire pour traiter des données dans une seule méthode :

void processScores(int[] scores) {
    class ScoreInfo {
        int score;
        boolean passed;

        ScoreInfo(int score) {
            this.score = score;
            this.passed = score >= 60;
        }
    }

    for (int s : scores) {
        ScoreInfo info = new ScoreInfo(s);
        System.out.println("Note: " + info.score + ", réussi: " + info.passed);
    }
}

4. Classes locales vs classes anonymes

On se demande parfois : à quoi servent les classes locales s’il existe des classes anonymes ? Voyons cela.

  • Classe locale — une classe nommée que l’on peut réutiliser plusieurs fois dans la méthode, à laquelle on peut ajouter des champs, plusieurs méthodes, des classes imbriquées.
  • Classe anonyme — une implémentation ponctuelle d’une interface ou d’un héritier, sans nom, généralement avec une seule méthode (ou la redéfinition d’une ou deux méthodes).

Quand les utiliser :

  • Si la logique est simple et requise une seule fois — utilisez une classe anonyme.
  • Si vous avez besoin de plusieurs méthodes ou champs, ou si la classe sera utilisée à plusieurs endroits de la méthode — utilisez une classe locale.

Exemple de comparaison

Classe anonyme :

Runnable r = new Runnable() {
    @Override
    public void run() {
        System.out.println("Rapide et anonyme!");
    }
};

Classe locale :

void doWork() {
    class MyWorker implements Runnable {
        @Override
        public void run() {
            System.out.println("Je suis une classe locale!");
        }
    }
    MyWorker worker = new MyWorker();
    worker.run();
}

5. Limitations et particularités des classes locales

  • Modificateurs d’accès : Une classe locale ne peut pas être déclarée public, private ou protected. Il est également impossible d’ajouter static.
  • Membres statiques : Une classe locale ne peut pas contenir de membres statiques, à l’exception des constantes (static final).
  • Périmètre de visibilité : Une classe locale n’est visible que dans le bloc où elle est déclarée.
  • Paramètres génériques : Une classe locale peut être générique si nécessaire.
  • Imbrication : Il est possible de déclarer des classes locales à l’intérieur d’autres classes locales (mais évitez d’en abuser, sinon le code finira par ressembler à une poupée russe).

6. Classes locales dans une application réelle

Poursuivons le développement de notre application d’apprentissage. Supposons que nous ayons une classe Quiz qui pose des questions à l’utilisateur et vérifie les réponses. Nous voulons, dans la méthode de vérification, créer une classe temporaire qui stockera la réponse de l’utilisateur et l’état de la vérification.

Exemple : utilisation d’une classe locale dans l’application

import java.util.Scanner;

public class Quiz {
    private String question = "Capitale de la France ?";
    private String correctAnswer = "Paris";

    public void runQuiz() {
        Scanner scanner = new Scanner(System.in);

        System.out.println(question);
        String userAnswer = scanner.nextLine();

        // Classe locale pour stocker le résultat
        class AnswerResult {
            String answer;
            boolean isCorrect;

            AnswerResult(String answer) {
                this.answer = answer;
                this.isCorrect = answer.equalsIgnoreCase(correctAnswer);
            }

            void printResult() {
                if (isCorrect) {
                    System.out.println("Correct!");
                } else {
                    System.out.println("Incorrect, bonne réponse : " + correctAnswer);
                }
            }
        }

        AnswerResult result = new AnswerResult(userAnswer);
        result.printResult();
    }
}

Ici, la classe AnswerResult n’existe qu’à l’intérieur de la méthode runQuiz et n’est utile nulle part ailleurs. C’est un excellent exemple de classe locale en pratique !

7. Erreurs courantes avec les classes locales

Erreur n° 1 : tentative d’accès à une variable de méthode qui n’est pas final ou effectively final.
Si vous avez déclaré une variable dans une méthode et que vous en modifiez la valeur après l’avoir utilisée dans une classe locale, le compilateur signalera immédiatement une erreur. Assurez‑vous toujours que ces variables ne changent pas après l’initialisation.

Erreur n° 2 : vouloir ajouter des modificateurs d’accès ou static.
Une classe locale ne peut pas être déclarée avec les modificateurs public, private, protected ni avec static. Si vous essayez — le compilateur s’y opposera.

Erreur n° 3 : tenter d’utiliser une classe locale en dehors de la méthode.
Une classe locale ne vit que dans la méthode (ou le bloc) où elle est déclarée. Elle n’est pas accessible depuis d’autres méthodes ni depuis l’extérieur de la classe.

Erreur n° 4 : abuser des classes locales pour une logique complexe.
Si votre classe locale devient trop volumineuse, contient de nombreuses méthodes ou champs — il est probablement préférable de l’extraire dans une classe séparée. Les classes locales sont adaptées aux tâches compactes et auxiliaires.

1
Mission
JAVA 25 SELF, niveau 16, leçon 3
Bloqué
Tableau d'affichage interactif : message temporaire de salutation 👋
Tableau d'affichage interactif : message temporaire de salutation 👋
1
Mission
JAVA 25 SELF, niveau 16, leçon 3
Bloqué
Gardien du secret : divulgation contrôlée du secret 🔐
Gardien du secret : divulgation contrôlée du secret 🔐
1
Mission
JAVA 25 SELF, niveau 16, leçon 3
Bloqué
Calculatrice spécialisée : affichage instantané de la somme ➕
Calculatrice spécialisée : affichage instantané de la somme ➕
1
Mission
JAVA 25 SELF, niveau 16, leçon 3
Bloqué
Analyseur de données textuelles : rapport succinct sur le nom 📊
Analyseur de données textuelles : rapport succinct sur le nom 📊
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION