IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

classe anonyme et paramétre final


Sujet :

Langage Java

  1. #21
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Points : 410
    Points
    410
    Par défaut
    Citation Envoyé par thelvin Voir le message
    À mon avis c'est plus compliqué que ça.
    En imposant que ces variables soient finales, les JLS imposent que tout se passe comme si elles étaient passées par copie implicite dans un bloc implicite d'initialisation.
    Comment ça fonctionne exactement ne nous regarde pas, mais l'idée du passage par copie semble "la plus simple."
    Cette façon de le présenter est tout à fait raisonnable et me convient parfaitement.


    Attention : la suite est une digression !
    Citation Envoyé par thelvin Voir le message
    On pourrait arguer que si.
    La bonne pratique n'est pas une fin en soi, elle sert une fin.
    Assez souvent, il s'agit d'être maintenable, par exemple en se relisant facilement et en pouvant être repris par beaucoup de gens. L'utilisation de syntaxes bien connues aide beaucoup.
    Cet argument est séduisant.
    Mais pour moi il reste théorique.
    On peut citer de nombreux cas où la plupart des codeurs utilisent (en général pour des raisons historiques) une mauvaise façon de faire qui est (ou a été) plus répandue , mais moins "correcte", et parfois moins lisible.
    en Java :
    • l'utilisation de raw types là où ce n'est pas nécessaire
    • l'utilisation de Vector
    • l'utilisation de String en lieu et place de StringBuilder/StringBuffer
    • l'absence d'utilisation d'annotations
    • ... je suis sur que tu en connais plus que moi

    en C++ :
    • l'utilisation de code et d'en-tête C (sprintf, malloc, <stdio.h>...)
    • la gestion de la mémoire "à la main"
    • toutes les techniques de soit-disant optimisation de lignes de code à la place du compilateur
    • ... en fait presque tous les points de la FAQ C++

  2. #22
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Points : 410
    Points
    410
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Non pas tout à fait. Les bloc static sont initialisé lors du chargement de la classe.
    Merci d'avoir corrigé cette erreur, il fallait bien sur lire "final" et non-pas "static".

  3. #23
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Feriaman Voir le message
    Merci d'avoir corrigé cette erreur, il fallait bien sur lire "final" et non-pas "static".
    Que le bloc soit final ou non ne change rien sur le moment précis où il sera initialisé

    a++

  4. #24
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Points : 410
    Points
    410
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Les variables d'instances sont initialisé pendant l'appel du constructeur, juste après l'appel du constructeur parent.
    Sauf les finales visiblement (cf l'articule sus-mentionné)

    Citation Envoyé par adiGuba;
    Une classe anonyme est une inner-classe... donc je ne vois pas ce que ca change
    Citation Envoyé par adiGuba Voir le message
    Cela montre juste qu'il faut éviter d'utiliser une méthode virtuelle dans un constructeur, cas avec l'héritage on peut se retrouver à manipuler des variables d'instances indéfinies...
    Citation Envoyé par adiGuba Voir le message
    Mais le besoin est quasi inexistant
    Je vois que c'est important pour toi d'avoir raison.
    Si je t'ai froissé, en remettant cela en cause, j'en suis désolé.
    Je ne souhaite pas du tout de te rabaisser ou avoir raison sur toi.

    D'ailleurs, je suis entièrement d'accord avec tes propos pleins de sagesse, preuve en sont les multiples citations que j'ai pu faire de toi dans ce thread.

  5. #25
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Points : 410
    Points
    410
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Que le bloc soit final ou non ne change rien sur le moment précis où il sera initialisé
    Comme tu as l'air sur de toi, j'ai vérifié : j'ai recopié dans une JVM windows le code de l'article : la réponse est correcte.

    La sortie console étant :
    0 4
    , j'en déduis que les variables i et j ne sont pas initialisées au même moment.

    Mais si tu la sortie console avait été "0 0", à ce moment-là j'en aurais déduis, comme toi, que l'initialisation des finales n'était pas différente de celle des non-finales (même si elle a lieu avant).

    Du coup, j'en ai profité pour tester ton code, et tu as raison, l'implémentation qui est faite passe bien par une recopie, via un constructeur avec paramètre.

  6. #26
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Citation Envoyé par Feriaman Voir le message
    Je vois que c'est important pour toi d'avoir raison.
    Permets-moi d'en douter.

    Je crois moi aussi que le besoin de classes locales non-anonyme n'existe pas ou peu.

    - C'est une syntaxe bien verbeuse, comparé à une classe anonyme.
    - Je vois déjà mes collègues se demander ce que c'est que cette "instruction class" au beau milieu d'une méthode.
    - Ça apporte quoi ?... Je ne vois que deux choses :
    -- une syntaxe explicite de l'utilisation des constructeurs. Ce qui peut être plus clair qu'une classe anonyme quand on veut faire appel aux constructeurs parents.
    -- si on veut utiliser plusieurs classes locales avec une qui hérite d'une autre, c'est un moyen d'éviter de dupliquer.
    Je ne suis pas très convaincu par ces raisons... Pour la première je préfèrerais définir une inner class non-locale. Pour la deuxième, je refactoriserais le code, ça devient trop compliqué.

    Citation Envoyé par Feriaman Voir le message
    Les variables d'instances sont initialisé pendant l'appel du constructeur, juste après l'appel du constructeur parent.
    Sauf les finales visiblement (cf l'articule sus-mentionné)
    Edit : ce qui suit est une grosse bêtise que j'ai écrite. Ça n'a rien à voir avec la choucroute.

    Hmm ? Tu confonds encore static et final. C'est vraiment deux choses qui ont juste rien à voir, d'autant plus qu'un membre peut être static final.

    Les variables static sont initialisées au chargement de la classe, bien avant l'appel du constructeur pour une instance.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #27
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Points : 410
    Points
    410
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Je crois moi aussi que le besoin de classes locales non-anonyme n'existe pas ou peu.. Pour la première je préfèrerais définir une inner class non-locale.
    Je ne poursuis pas le débat. Je pense qu'on peut se mettre d'accord sur : "le besoin n'existe que peu, mais lorsqu'il existe, l'inner class est une solution"


    Citation Envoyé par thelvin Voir le message
    Edit : ce qui suit est une grosse bêtise que j'ai écrite. Ça n'a rien à voir avec la choucroute.
    ...
    Je ne suis pas vexé que tu aie pu penser cela. D'ailleurs, j'ai moi-même fait le lapsus en l'écrivant dans un post précédent (comme me l'a fait remarqué AdiGuba). Cependant, je confirme que je ne confonds pas les deux concepts.

  8. #28
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Oui, pardon, je me suis trompé de page.

    Sauf les finales visiblement (cf l'articule sus-mentionné)
    En fait, c'est plus compliqué que ça, là c'est une ambiguïté de Java.

    Il existe deux genres de variables finales :
    - Les expressions constantes. Une variable finale initialisée à sa déclaration par une expression constante, devient elle-même une expression constante.

    4 étant une expression constante, j est aussi une expression constante dans tout son scope.

    - Les autres. Celles qui ne sont pas initialisées dans leur déclaration, ou alors par une expression non-constante.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    final int j = Math.min(4, 5);
    Un appel de méthode n'est pas une expression constante, le compilateur ne peut pas évaluer son résultat.
    j ne sera donc pas une expression constante.


    Donc : en Java, une expression constante est évaluée directement par le compilateur, bien avant le chargement de la classe ou l'appel du constructeur.
    Une telle chose est impossible avec les expressions non-constantes.

    Ce qui conduit, hélas, à deux genres différents de variables final, différents en terme de à quel moment elles sont initialisées, et est-il possible de les choper non-initialisées. En pratique, cette différence ne se voit pas souvent. Et elle est fuie comme la peste par les habitués.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  9. #29
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Points : 410
    Points
    410
    Par défaut
    Citation Envoyé par thelvin Voir le message
    En fait, c'est plus compliqué que ça, là c'est une ambiguïté de Java.
    Il existe deux genres de variables finales :
    - Les expressions constantes.
    ...
    - Les autres.
    Merci pour cette information, qui est neuve pour moi.

    Mais du coup, si j'essaie de boucler le raisonnement, je ne comprends plus pourquoi les expressions constantes "locales" sont copiées dans les inner-class locales via le constructeur. Elles pourraient très bien être des expressions constantes pour l'inner-class.

  10. #30
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Citation Envoyé par Feriaman Voir le message
    Mais du coup, si j'essaie de boucler le raisonnement, je ne comprends plus pourquoi les expressions constantes "locales" sont copiées dans les inner-class locales via le constructeur. Elles pourraient très bien être des expressions constantes pour l'inner-class.
    Elles le sont. Mais c'est un cas très spécifique... Puisque c'est une expression constante, elle a peu de chances d'être déclarée dans le scope local.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  11. #31
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par Feriaman Voir le message

    Je ne comprends pas pourquoi vous voulez absolument utiliser des classes anonymes, et bidouiller un constructeur, alors que le Java propose justement le mécanisme des Inner Classes pour répondre à cela.
    Pour moi, une inner classe définie dans une fonction fait exactement comme une classe anonyme, mais avec un constructeur.
    Si vous lisiez mon message, vous verriez que je mensionne justement que j'ignorais qu'on pouvais mettre une Inner class dans une méthode qui ne soit pas anonymé, d'ou mes problèmes par le passé pour initialiser mes classes anonymes

  12. #32
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Points : 410
    Points
    410
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Elles le sont. Mais c'est un cas très spécifique... Puisque c'est une expression constante, elle a peu de chances d'être déclarée dans le scope local.
    Bien vu !
    D'ailleurs, j'aurais du m'en douter quand j'ai vu le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    final String localvar;
    localvar = "World";
    En effet, comme tu le dis, si on le remplace par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    final String localvar = "World";
    La signature du constructeur passe de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Test$1Inner2(Test,java.lang.String)
    à
    Ceci conclus pour moi cette discussion, et c'est bien toi qui avait raison en disant :
    En imposant que ces variables soient finales, les JLS imposent que tout se passe comme si elles étaient passées par copie implicite dans un bloc implicite d'initialisation.
    Dans le cas d'une finale non-constante, cela revient à la passer par copie dans le constructeur, alors que dans le cas d'une finale constante, cela revient à dupliquer la finale constante.

    [EDIT] Cela fait plaisir de discuter avec des gens qui ont une compréhension aussi fine du Java.[/EDIT]

  13. #33
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Lorsqu'on utilise une constante, le compilateur remplace directement toutes les occurrences de la variable par sa valeur dès la compilation.

    On peut vérifier cela facilement avec la classe Derived de l'exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Derived extends Base{
     
        int i = 4;
     
        final int j = 4;
     
        void init() { System.out.println ( i +" "+j); }
     
    }
    Si on décompile ce code avec javap :
    On obtiens quelque chose comme cela pour la méthode init() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    void init();
      Code:
       0:   getstatic       #24; //Field java/lang/System.out:Ljava/io/PrintStream;
       3:   new     #30; //class java/lang/StringBuilder
       6:   dup
       7:   aload_0
       8:   getfield        #15; //Field i:I
       11:  invokestatic    #32; //Method java/lang/String.valueOf:(I)Ljava/lang/String;
       14:  invokespecial   #38; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
       17:  ldc     #41; //String
       19:  invokevirtual   #43; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       22:  iconst_4
       23:  invokevirtual   #47; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
       26:  invokevirtual   #50; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
       29:  invokevirtual   #54; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
       32:  return
    Outre le fait que la concaténation utilise la classe StringBuilder, on peut voir qu'il y a deux types d'accès différents aux attributs i et j.
    • L'attribut d'instance i est accéder via l'instruction getfield qui va lire la vrai valeur du champ.
    • L'attribut d'instance j est final et constant, et il est donc directement remplacé par sa valeur dès la compilation. Le bytecode contient donc directement la valeur de la constante (iconst_4)


    On peut vérifier ce comportement en vérifiant la valeur des champs via la reflection :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    class Derived extends Base{
     
        int i = 4;
     
        final int j = 4;
     
        void init() {
        	System.out.println ( i +" "+j);
        	try {
        		System.out.println ( "i = " + getClass().getDeclaredField("i").getInt(this) );
        		System.out.println ( "j = " + getClass().getDeclaredField("j").getInt(this) );
        	} catch (Exception e) {
        		e.printStackTrace();
        	}
        }
     
    }
    On obtient alors ceci :
    Le champ final est initialisé au même moment que son homologue non-final. La différence vient du fait qu'il s'agit d'une constante.



    En clair :
    • Si possible, les constantes sont remplacées par leurs valeurs dès la compilation.
    • Les attributs static sont initialisés au chargement de la classe.
    • Les attributs d'instance sont initialisés à la création de la classe, entre l'appel du constructeur parent et le code du constructeur courant.



    a++

    PS : Je ne cherche pas à avoir raison à tout prix - je te rassure j'ai déjà dit plein de conneries sur le forum
    C'est juste que cela touche des fonctionnements assez variés et intéressant

  14. #34
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Ouch, mais c'est vrai !

    Les constantes restent également des variables membres récupérables par réflexion, et qui, alors, peuvent avoir été initialisées ou pas encore.
    Ce qui rend possible qu'elles aient une valeur différente par réflexion ou par accès direct.

    Franchement, c'est abominable -_-°. (Non, je ne pense pas pouvoir faire mieux, mais bouh T_T.)
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  15. #35
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Les constantes restent également des variables membres récupérables par réflexion, et qui, alors, peuvent avoir été initialisées ou pas encore.
    Ce qui rend possible qu'elles aient une valeur différente par réflexion ou par accès direct.
    C'est seulement le cas pendant l'exécution des constructeurs parents...

    Ce qui n'arrive pas si on évites d'utiliser des méthodes virtuelles dans le constructeur (ce qui est généralement déconseillé).

    a++

  16. #36
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Ce qui n'arrive pas si on évites d'utiliser des méthodes virtuelles dans le constructeur (ce qui est généralement déconseillé).
    Et décoré d'un joli liseret jaune dans netbeans

    Malheureusement, il est parfois nécessaire de faire appel à une méthode virtuelle dans un constructeur, quand on veux que l'enfant puisse intervenir pendant la construction du parent. Mais faut être prudent et bien documenter

  17. #37
    Membre chevronné
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Points : 1 806
    Points
    1 806
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    C'est juste que cela touche des fonctionnements assez variés et intéressant
    Et d'ailleurs je remercie les différents participants, ce thread est vraiment très intéressant à lire, j'me sens moins bête

  18. #38
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Franchement, c'est abominable -_-°. (Non, je ne pense pas pouvoir faire mieux, mais bouh T_T.)

    Tiens mange

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public class TestInner {
        static int count = 0;
        int id = count++;
        public class Inner {
            int id = count++;
            public class SubInner {
                int id = count++;
                public void whoAreYou() {
                    System.out.println("SubInner "+id+
                            " inside Inner " + Inner.this.id +
                            " inside TestInner " + TestInner.this.id);
                }
            }
        }
        public static void main(String[] argv) {
            TestInner in = new TestInner();
            in.new Inner().new SubInner().whoAreYou();
     
        }
    }
    edit: si quelqu'un connait une notation (autre que de créer un getter), qui permettrais à partir de SubInner de retrouver Inner, je suis preneur, je me gratte la tête pour trouver quelque chose de similaire à ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SubInner sub = in.new Inner().new SubInner();
    Inner inner = sub.Inner.this;
    pour le moment j'ai que cette horreur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ((Inner) Inner.SubInner.class.getDeclaredField("this$1").get(sub)).new SubInner().whoAreYou();

  19. #39
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Octobre 2009
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Octobre 2009
    Messages : 76
    Points : 80
    Points
    80
    Par défaut
    Un sujet intéressant

    j'ai lu la phrase suivante dans "au coeur de java" vol.1
    [..Une variable locale déclarée final ne peut pas être modifiée après avoir été initialisée. Ainsi, nous avons la garantie que la variable locale et sa copie dans la classe locale auront bien la même valeur..]


    et sur la page de JM Doudoux dans les cours et tutoriels Java (chap POO)
    [....Leur particularité, en plus d'avoir un accès aux membres de la classe principale, est d'avoir aussi un accès à certaines variables locales du bloc où est définie la classe interne.

    Ces variables définies dans la méthode (variables ou paramètres de la méthode) sont celles qui le sont avec le mot clé final. Ces variables doivent être initialisées avant leur utilisation par la classe interne. Elles sont utilisables n'importe où dans le code de la classe interne.

    Le modificateur final désigne une variable dont la valeur ne peut être changée une fois qu'elle a été initialisée.

    Cette restriction est imposée par la gestion du cycle de vie d'une variable locale. Une telle variable n'existe que durant l'exécution de cette méthode. Une variable finale est une variable dont la valeur ne peut être modifiée après son initialisation. Ainsi, il est possible sans risque pour le compilateur d'ajouter un membre dans la classe interne et de copier le contenu de la variable finale dedans.

    Pour permettre à une classe interne locale d'accéder à une variable locale utilisée dans le bloc de code où est définie la classe interne, la variable doit être stockée dans un endroit où la classe interne pourra y accéder. Pour que cela fonctionne, le compilateur ajoute les variables nécessaires dans le constructeur de la classe interne.

    Les variables accédées sont dupliquées dans la classe interne par le compilateur. Il ajoute pour chaque variable un membre privé dans la classe interne dont le nom est de la forme val$nom_variable. Comme la variable accédée est déclarée finale, cette copie peut être faite sans risque. La valeur de chacune de ces variables est fournie en paramètre du constructeur qui a été modifié par le compilateur.

    Une classe qui est définie dans un bloc de code n'est pas un membre de la classe englobante : elle n'est donc pas accessible en dehors du bloc de code où elle est définie. Ses restrictions sont équivalentes à la déclaration d'une variable dans un bloc de code.

    Les variables ajoutées par le compilateur sont préfixées par this$ et val$. Ces variables et le constructeur modifié par le compilateur ne sont pas utilisables dans le code source....]

Discussions similaires

  1. Serialization et classe anonyme
    Par vincent63 dans le forum Langage
    Réponses: 6
    Dernier message: 07/07/2006, 19h03
  2. Variable d'instance et classe anonyme
    Par zoullou dans le forum AWT/Swing
    Réponses: 7
    Dernier message: 21/05/2006, 12h30
  3. [Débutant]Passer une classe abstraite en paramètre
    Par Invité dans le forum Débuter
    Réponses: 2
    Dernier message: 06/01/2006, 17h56
  4. Réponses: 5
    Dernier message: 16/08/2005, 10h30
  5. [classe anonyme] implementant une interface
    Par stanilas dans le forum Langage
    Réponses: 4
    Dernier message: 30/11/2004, 00h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo