Surcharger les méthodes à la volée

Lorsqu’un projet intègre plusieurs librairies Open Source, il est parfois nécessaire de modifier le comportement d’une méthode d’un composant. Afin de ne pas surcharger votre projet avec la création de classes d’extension je vous propose de n’écrire que le morceau de code à modifier, directement au moment où l’on instancie le composant qui nous intéresse. Nous allons surcharger les méthodes à la volée!

C’est facile à maintenir et rapide à écrire. Techniquement, il s’agit de classes internes anonymes (inner anonymous class). C’est pas nouveau, mais on ne les voit pas souvent.

Pour l’exemple, nous allons surcharger la méthode toString() de la classe ArrayList de l’API java.util. Nous allons donc créer un simple projet console avec une méthode main :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class InnerAnonymousClass {
    public static void main(String[] args) {
        
        //Création d'une instance de la classe interne anonyme qui étend la classe standard "ArrayList"
        List<String> developpeurs = new ArrayList<String>(){
            @Override
            public String toString(){
                //Si la liste est vide, on affiche "liste vide"
                if(size() == 0) return "Liste vide.\n";
                //Sinon, on concatène une liste des valeurs
                StringBuilder sb = new StringBuilder("Liste des développeurs : \n");
                for (int i = 0; i < size(); i++) {
                    sb.append("\t- ").append(get(i)).append("\n");
                }
                return sb.toString();
            }
        };
        
        //On affiche la liste vide
        System.out.println(developpeurs.toString());
        
        //On remplit la liste
        developpeurs.add("Joshua J.Bloch");
        developpeurs.add("James Gosling");
        developpeurs.add("Doug Lea");
        //On affiche la liste pleine
        System.out.println(developpeurs.toString());
        
        //On clone la liste avec la classe ArrayList standard
        List<String> listeTemoin = new ArrayList<String>(developpeurs);
        //On appelle sa méthode toString pour comparer les résultats
        System.out.println(listeTemoin.toString());
    }
}

En console on peut voir une belle implémentation de la méthode toString(), adaptée à notre projet console :

Liste vide.

Liste des développeurs :
    - Joshua J.Bloch
    - James Gosling
    - Doug Lea

Et l’implémentation standard adaptée à l’affichage dans le debugger d’Eclipse :

[Joshua J.Bloch, James Gosling, Doug Lea]

Restrictions : on ne peut pas faire hériter une classe (anonyme ou non) d’une classe marquée par le mot clé « final« .