jeudi 6 septembre 2012

Java : classes internes locales

Contexte : une classe interne locale (local inner class) ne peut pas modifier les variables locales à la méthode.
Ref : http://renaud.waldura.com/doc/java/final-keyword.shtml#vars

Par exemple, le code suivant ne compile pas :

    private Adaptation createInstance__DoesNotCompile() throws OperationException
        {
            final Adaptation instance;
            Procedure proc = new Procedure()
            {
                public void execute(ProcedureContext aContext) throws Exception
                {
                    //  OUCH
                    instance = aContext.doCreateRoot(
                        SCHEMA_LOCATION,
                        REFERENCE,
                        DirectoryForTest.DEFAULT_USER_REF);
                }
            };
   
            this.execute(proc);
            return instance;
        }




Comment faire, alors, pour retourner l'instance créée dans la classe locale ?
=> plutôt qu'une classe anonyme, déclarer une classe nommée :

    private Adaptation createInstance() throws OperationException
    {
        class CreationProcedure implements Procedure
        {
            Adaptation instance;
            public void execute(ProcedureContext aContext) throws Exception
            {
                this.instance = aContext.doCreateRoot(
                    SCHEMA_LOCATION,
                    REFERENCE,
                    DirectoryForTest.DEFAULT_USER_REF);
            }
        }
        ;

        CreationProcedure proc = new CreationProcedure();
        this.execute(proc);
        return proc.instance;
    }



http://stackoverflow.com/questions/7423028/java-local-variable-visibility-in-anonymous-inner-classes-why-is-final-keywo




De façon générale, les classes internes ne sont pas recommandées,
principalement parce que c'est une construction supplémentaire et non
nécessaire du langage Java et qui ajoute quelques complexités.

Mais on les utilise quelquefois à des fins pratiques de meilleure
lisibilité (unité syntaxique, encapsulation), surtout dans les cas suivants :


- classe interne locale et nommée (ci-dessus).
- classe interne locale et anonyme.
Par exemple "new Procedure(){...}" dans une méthode.
- classe interne statique et privée.
Implémente une sous-structure simple et purement interne à la classe contenante.

Dans tous les cas les implémentations doivent rester légères : l'unité
syntaxique et l'encapsulation sont certes améliorées, mais il ne faut
pas que la structure contenante soit trop alourdie.

On essaie d'éviter les autres cas, en particulier les classes locales
"private class

CriteriaData {...}" (il n'y a pas le "static") car elles préservent un
pointeur dans leur contexte de définition.