Classes imbriquées en Java : par où tout a commencé ?
Imaginez : vous écrivez du code en Java, et soudain vous réalisez qu'une classe est logiquement et indissociablement liée à une autre. Par exemple, Car et Engine. Le moteur n'existe pas par lui-même — il fait partie de la voiture. Comment modéliser cela de manière élégante et correcte en Java ? La réponse — les classes imbriquées (nested classes).
Le sujet Java inner class and static nested class est l'un des plus fréquents sur Stack Overflow. Des milliers de développeurs s'y perdent : quelle est la différence ? Quand utiliser inner et quand utiliser static nested ? Pourquoi ont-elles été inventées ?
Dans ce tutoriel, nous allons tout clarifier. Vous n'apprendrez pas seulement la syntaxe — vous comprendrez la logique des concepteurs de Java. C'est parti !
Qu'est-ce qu'une nested class (classe imbriquée) ?
Commençons par les bases. Une nested class est une classe déclarée à l'intérieur d'une autre classe. En Java, il existe quatre types de classes imbriquées, mais aujourd'hui nous nous intéressons aux deux plus populaires :
- Static nested class (classe imbriquée statique)
- Inner class (classe interne, également appelée non-static nested class)
La différence clé est le modificateur statique. Il change tout : de l'accès aux champs à la durée de vie de l'objet. Voyons cela en pratique.
Static nested class : simple et indépendante
Une classe imbriquée statique se comporte comme une classe externe ordinaire, mais « vit » à l'intérieur de sa classe parente. Elle n'a pas accès aux champs et méthodes non statiques de la classe externe (sauf si elle reçoit une référence à un objet).
Exemple concret : Database et DatabaseConfig. La configuration n'est pas liée à une instance spécifique de la base de données.
public class Database { private String url; private static String defaultDriver = "com.mysql.cj.jdbc.Driver";
public Database(String url) { this.url = url; }
// Static nested class public static class DatabaseConfig { private String driver; private int poolSize;
public DatabaseConfig(String driver, int poolSize) { this.driver = driver; this.poolSize = poolSize; }
public void printConfig() { // A accès uniquement aux membres statiques de la classe externe System.out.println("Pilote par défaut : " + defaultDriver); // System.out.println(url); // ERREUR ! url est un champ non statique }
public static void staticMethodInNested() { System.out.println("Méthode statique dans une classe imbriquée statique"); } }
public void useConfig() { // Création d'une instance de static nested class DatabaseConfig config = new DatabaseConfig("oracle.jdbc.OracleDriver", 10); config.printConfig(); }}Remarque : pour créer DatabaseConfig, nous n'avons pas besoin d'un objet Database. C'est le principal avantage — l'indépendance.
Quand utiliser static nested class ?
- Lorsque la classe imbriquée est logiquement liée à la classe externe, mais ne dépend pas de son instance.
- Lorsque vous devez regrouper des classes auxiliaires (builders, configurations, utilitaires).
- Lorsque vous concevez le pattern Builder — un exemple classique.
Inner class (non-static nested class) : liée pour toujours
La classe interne est le contraire complet. Elle est toujours liée à un objet spécifique de la classe externe. Cela signifie :
- Elle a accès à tous les champs et méthodes de la classe externe (même privés).
- Elle ne peut pas exister sans une instance de la classe externe.
- Elle stocke implicitement une référence à l'objet externe (
OuterClass.this).
Exemple : Car et Engine. Chaque voi