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 :

L'apparition du mot-clé const est-il prévu dans une version à venir du JDK?


Sujet :

Langage Java

  1. #1
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    605
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 605
    Points : 670
    Points
    670
    Par défaut L'apparition du mot-clé const est-il prévu dans une version à venir du JDK?
    Depuis une très longue période, le mot-clé const est marqué réservé par dans de nombreux éditeurs IDE Java, tels qu'Eclipse, qui le colorie comme un mot-clé réservé du langage même s'il en interdit l'emploi dans le même temps.

    Le mot-clé const a un sens différent de final.

    Car si final appliqué à une variable ou variable membre protège une référence et interdit à son pointeur de désigner autre chose que cette variable, const est supposer protéger effectivement cette variable contre des modifications par, entre-autres, des fonctions membres modificatrices.


    C'est ainsi que dans ce code d'exemple, pourvu d'un mot-clé final, ce mot-clé ne protège pas le contenu de la variable sur laquelle il s'applique. Et par là, je trouve son usage d'un intérêt limité.

    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
    /** Une personne. */
    class Personne
    {
    /** Le nom de la personne. */
    private String m_szNom;
     
       /** Construire une personne qui a un nom. */
       public Personne(String szNom) {setNom(szNom);}
     
       /** Renvoyer le nom de la personne. */
       public String getNom() {return(m_szNom);}
     
       /** Fixer le nom de la personne. */
       public void setNom(String szNom) {m_szNom = szNom;};
    }
     
    /** Un programme d'essai. */
    public class Essai
    {
    /** Un monsieur 'final'. */
    private final Personne monsieur = new Personne("Remulus");
     
       /** Un essai qui montre que final ne protège pas le contenu du monsieur. */
       public void unEssai()
       {
          System.out.println("Avant: " + monsieur.getNom());
          monsieur.setNom("Rébus");
          System.out.println("Après: " + monsieur.getNom());
       }
     
       /** Lancement de l'essai. */
       public static void main(String[] args)
       {
          new Essai().unEssai();
          System.exit(0);
       }
    }
    A l'exécution:
    C:\build\classes>java -cp . Essai
    Avant: Remulus
    Après: Rébus

    (en revanche, dans mon code source, je n'aurais pas pu écrire ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
       public void unEssai()
       {
          System.out.println("Avant: " + monsieur.getNom());
          monsieur.setNom("Rébus");
          System.out.println("Après: " + monsieur.getNom());
          monsieur = new Personne("Charade");
       }
    car j'aurais cherché à changer l'affectation du pointeur monsieur).


    Alors, bien entendu, il existe le pattern immutable. Mais il pose un problème: il n'offre pas de garantie.

    Je peux par principe vous présenter une classe nommée TotoImmutable, et malheureusement, soit par oubli, soit par erreur, elle ne l'est pas réellement...

    Seul un mot-clé const, je crois, permettrait d'être réellement rassuré.
    Qu'en est-il de sa venue? Est-elle prévue?

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    121
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 121
    Points : 98
    Points
    98
    Par défaut
    je crois qu'elle est prevue

  3. #3
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Citation Envoyé par grunt2000
    Alors, bien entendu, il existe le pattern immutable. Mais il pose un problème: il n'offre pas de garantie.
    Il me semble que si, non ?...

    Cela dit, même si je ne suis pas sûr que le cas particulier des const soit très intéressant, j'aimerais, moi aussi, que le langage évolue vers une plus grande expressivité.

    Soit le pattern de immutable qui est, je pense, garanti dès l'instant que l'on en respecte les règles. Tu pourrais toujours me répondre que l'on peut toujours se tromper. Et que ce serait bien, que grâce à un mot clef le compilateur vérifie cette qualité, et tu aurais raison.

    En ce genre de cas je me fais une sorte de règle de nommage, et j'essaie de trouver un test à la mode JUnit.
    Mieux que Google, utilisez Sur Java spécialisé sur la plate-forme java !
    Pour réaliser vos applications Java dans le cadre de prestations, forfait, conseil, contactez-moi en message privé.

  4. #4
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    bof, y a "static" voir "static final" pour faire la même chose...
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Après avoir lu ton post ce matin, j'y ai réfléchi en allant en cours, et pour moi ce concept de const n'est pas applicable.

    En fait, 2 possibilités:

    - soit le const est un modifieur d'une variable, exactement comme final
    Il y a ici un gros problème, c'est que le mot-clé const s'applique à une variable (donc à une référence), alors que le concept (l'immutabilité) s'applique sur l'instance de l'objet.
    Ainsi, tu peux faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    const UnObjet o = new UnObjet();
    UnObjet o2 = o;
    o2.methodeQuiModifie();
    Une solution serait d'interdire l'affectation d'une variable const vers une non const, mais aussi d'une non const vers une const (car il faut soit que toutes les références soient const, soit qu'elles soient toutes non const).

    Mais là cela pose des problèmes. Imagine tu as une méthode qui prend en paramètre une instance de type UnObjet. Déjà ce qui est passée est une copie de la référence, donc il faut que le compilateur sache que c'était une const. Mais admettons.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public static void methode(UnObjet o) {
        o.methodeQuiModifie();
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    const UnObjet o = new UnObjet();
    methode(o); // ne marche pas, car o est const, et la méthode attend un non const
    et inversement:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public static void methode2(const UnObjet o) {
        o.uneMethode();
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    UnObjet o = new UnObjet();
    methode2(o); //ne marche pas, l'objet doit être constant

    Ceci est quand même très embêtant.


    De plus, si une variable est déclarée const, il serait impossible de créer un objet const sans l'affecter à une variable.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    new const UnObjet(); //pourquoi pas? pas terrible quand même...
    Donc cette première solution est incohérente, car le mot-clé const s'applique à une variable (donc à une référence), alors que le concept (l'immutabilité) s'applique sur l'instance de l'objet.


    - soit const serait un modifieur de classe, pour faire par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public const class UneClasse {...}
    Ceci permettrait de vérifier l'immutabilité à la compilation.

    On se pose alors la question, comment vérifier l'immutabilité à la compilation?

    - il faut vérifier récursivement que les attributs de type primitifs sont finaux, et que les attributs références sont soit finaux, soit constants.
    Pour les finaux, c'est facile.
    Pour les constants, on a vu dans le premier point que const ne devait pas s'appliquer à une variable, donc il faudrait que la classe de chacun des attributs soit const (immutable).

    Or, avec le pattern immutable, on peut avoir des composants mutables tout en garantissant une classe immutable.
    par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class Immutable {
        private Point point;
        public Immutable(int x, int y) {
            point = new Point(x,y);
        }
        public int getX() {
            return point.getX();
        }
        public int getY() {
            return point.getY();
        }
    }
    Une solution pourrait être de vérifier que les attributs de type non const ne soit jamais affectés à partir d'un paramètre, et qu'il n'y a pas de getter dessus... (récursivement!)

    (en y réfléchissant, pourquoi pas)



    Voilà pourquoi je pense que ça ne serait finalement pas une avancée aussi intéressante qu'il n'y parait...
    Sans parler de la compatibilité ascendante, des classes qui sont immutables par le pattern, qui devraient être composées dans des classes "const" alors qu'elles ne sont elles-même pas const (bien qu'immutable).


    Pour prendre un peu de recul, si on introduit un mot-clé (du moins son utilisation, car il existe déjà sans être utilisé) pour un design-pattern, pourquoi ne pas introduire également d'autres mots-clés : singleton, listener...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public singleton class MonSingleton { ... }
    ...

  6. #6
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    605
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 605
    Points : 670
    Points
    670
    Par défaut
    @gifftane: les choses sont exactement comme tu les dis. Le pattern immutable fonctionne très bien dès que l'on en respecte les règles. Mais toi recevant utilisant une classe "Immutable" dont tu ne sais rien de l'auteur ou du code, tu ne peux qu'espérer qu'elle est bonne.

    Il existe un cas de figure, où sauf à me tromper lourdement (c'est possible!!!), l'emploi du const semble indispensable. Il s'agit des EJB Stateless Remote et Local.

    Lorsque j'ai décris ce point d'entrée de service dans un EJB Stateless:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    public void valider(Commande cmd)
    {
        ....
    }
    Si l'EJB a une interface Remote, c'est un mécanisme JRNP/RMI/SOAP qui est mis en place et celui-là transmet le paramètre cmd par valeur. S'il est par hasard modifié par la méthode valider, l'appelant n'en saura rien en retour. Il n'en sera pas affecté parce le contenu de cmd ne lui sera pas retourné.

    En revanche, si l'EJB a une interface Locale, l'appel est - sauf mauvaise interprétation de ma part - direct. Les n couches de marshalling et unmarshalling disparaissent, et l'on a affaire à un appel Java classique, normal, où le paramètre cmd est cette fois passé par référence. Et par là, s'il est modifié dans la méthode valider, il sera restitué modifié à l'appelant.

    En passant Remote à Local, nous provoquons un changement de comportement potentiel dans notre application, aux effets de bords inattendus.

    Mais comment envisager sur cent, deux cents, cinq cents points d'entrée de service que nous aurions écrits ceux succeptibles de nous gêner, en mode Local?

    En mettant les paramètres d'entrées des services const, pour déclarer qu'au sein des méthodes EJB Stateless nous entendons bien ne pas les modifier, et demander au compilateur de vérifier ce fait.


    @om: Le mot-clé const existe et fonctionne. Il est implémenté en C++, et peut-être dans d'autres langages.

    Cela dit, const impose l'usage de règles comme tu l'as pensé.
    Par exemple, un objet const ne peut être passé qu'au travers d'une fonction annoncée const (c'est à dire ne modifiant pas l'objet this auquel elle va s'appliquer), ainsi que quelques autres règles.

  7. #7
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Même s'il n'y a rien pour garantir l'immutabilité (dont il resterait à établir la relation avec const, je ne sais pas exactement comment notre ami à l'origine du post voit les choses), tu peux jouer avec le mot clef final.

    Si ce terme ne garanti pas la constance de ses composants, il garanti au moins la constance de lui même, ce qui est déjà bien ! Pour les composants tu peux aussi leur affecter un final, pour les composants des composants aussi, etc.

    Tu peux régler ainsi le coté immuable d'un objet, mais jamais garantir sur la totalité. Mais moi je trouve que c'est déjà bien et intéressant.
    Mieux que Google, utilisez Sur Java spécialisé sur la plate-forme java !
    Pour réaliser vos applications Java dans le cadre de prestations, forfait, conseil, contactez-moi en message privé.

  8. #8
    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
    Salut,


    Citation Envoyé par gifffftane
    Alors, bien entendu, il existe le pattern immutable. Mais il pose un problème: il n'offre pas de garantie.

    Je peux par principe vous présenter une classe nommée TotoImmutable, et malheureusement, soit par oubli, soit par erreur, elle ne l'est pas réellement...
    Si le pattern immuable est bien respecté, le seul moyen de passer outre l'immuabilité est de passer par la reflection et des setAccessible(), mais on est loin de l'erreur ou de l'oubli...



    Citation Envoyé par audran12
    je crois qu'elle est prevue
    Source ?




    bof, y a "static" voir "static final" pour faire la même chose...
    Non ce n'est pas du tout la même chose...

    static permet de déclarer des attributs ou des méthodes de classes (au lieu d'instance).
    final permet soit d'empêcher de redéfinir une méthode, soit d'empêcher de modifier la valeur d'une variable. Mais pour un objet cela empêche seulement de modifier la valeur de la référence, et le contenu de l'objet reste modifiable via ses mutateurs...


    Le const du C++ est différent :
    • Sur une méthode d'instance, il indique que cette méthode ne modifie pas la valeur de l'objet courant.
    • Sur une variable (locale, attribut ou paramètre), il indique que l'on ne doit pas modifier la valeur de l'objet référencé. Ainsi on ne peut appeler que les méthodes marqué const...


    Ce mot-clef permet, couplé avec le passage de référence, d'éviter de multiples copies d'objets inutile...


    Dès le début Java a adopté une autre approche, en se basant sur les classes immuables...


    Enfin je ne suis pas sûr que l'intégration du mot clef const soit évidente :
    • Soit les classes l'API standard sont modifiées afin de l'utiliser, et dans ce cas on peut se retrouver avec un grand nombre d'incompatibilitée (que se passerait-il si je redéfinit une méthode const sans respecter son "contrat" ?).
    • Soit les classes de l'API ne l'utilisent pas, et dans ce cas il perdrait beaucoup de son intérêt...



    a++

    PS : avant de poster je viens de voir qu'il y a eu plusieurs autres posts : ®om la plupart des cas problématique que tu cites génèreraient des erreurs de compilations (c'est le principe du const )

  9. #9
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    605
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 605
    Points : 670
    Points
    670
    Par défaut
    Avec const, mon programme deviendrait ceci:

    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
    /** Une personne. */
    class Personne
    {
    /** Le nom de la personne. */
    private String m_szNom;
     
       /** Construire une personne qui a un nom. */
       public Personne(String szNom) {setNom(szNom);}
       
       /** Renvoyer le nom de la personne. */
       public String getNom() const {return(m_szNom);}
       
       /** Fixer le nom de la personne. */
       public void setNom(String szNom) {m_szNom = szNom;};
    }

    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
    21
    22
    /** Un programme d'essai. */
    public class Essai
    {
    /** Un monsieur 'const'. */
    private const Personne monsieur = new Personne("Remulus");
     
       /** Un essai. */
       public void unEssai()
       {
          System.out.println("Avant: " + monsieur.getNom());
          monsieur.setNom("Rébus");
          System.out.println("Après: " + monsieur.getNom());
       }
     
       /** Lancement de l'essai. */
       public static void main(String[] args)
       {
          new Essai().unEssai();
          System.exit(0);
       }
    }
    La ligne en rouge me serait interdite dès la compilation.

    Intérêt? Cela évite de créer une classe immutable, qui oblige:
    - à créer une classe, PersonneImmutable, compagnone de Personne, et reprenant tous ses getters.

    - soit à procéder par copie d'objet à l'intérieur de cette classe immutable, mais alors on a une consommation de temps, de mémoire, et le risque - toujours - d'avoir fait... une mauvaise méthode clone ou d'avoir fait un new Personne() mais en oubliant de recopier la totalité des valeurs de ses membres qui seraient utiles.

    - soit de définir l'immutabilité de la Personne comme une interface Immutable interne à la classe Personne, et qui ne reprend que les getters. Mais alors on perd les éventuels héritages et implémentations de Personne lorsque l'on retourne une PersonneImmutable.


    A mes yeux, donc, const est nettement plus élégant. Plus propre.


    @adiGuba:
    Enfin je ne suis pas sûr que l'intégration du mot clef const soit évidente :

    Soit les classes l'API standard sont modifiées afin de l'utiliser, et dans ce cas on peut se retrouver avec un grand nombre d'incompatibilitée (que se passerait-il si je redéfinit une méthode const sans respecter son "contrat" ?).

    Je ne pense pas que la redéfinition d'une méthode permettrait d'oublier son mot-clé. Il suffit d'écrire le compilateur et la JVM d'une manière qui convient.

    Soit les classes de l'API ne l'utilisent pas, et dans ce cas il perdrait beaucoup de son intérêt...
    Il faut effectivement repasser sur toutes les APIs, mais en limitant cependant son action aux prototypes des fonctions dans la majorité des cas.
    C'est un travail certainement fastidieux pour Sun, mais à tout prendre, je pense, moins que celui d'avoir mis en place les génériques.

  10. #10
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Citation Envoyé par adiGuba
    ®om la plupart des cas problématique que tu cites génèreraient des erreurs de compilations (c'est le principe du const )
    Justement, parfois c'est génant, si tu fais une méthode print(String),
    il faut faire 2 méthode: print(String) et print(const String)...
    ça double pas mal de méthodes...

    Et une méthode qui renvoie un String, il faudrait définir si ce que ça renvoie c'est un const ou pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public const String a();
    et (il ne serait pas possible de le déterminer à la récupération, car on ne peut pas affecter un const à un non const et vice-versa - cf mon premier post-).

  11. #11
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Citation Envoyé par grunt2000
    La ligne en rouge me serait interdite dès la compilation.
    Il y a possibilité de faire quelque chose de parfaitement similaire, du moins il me semble, en java :

    (je commente les points importants dans le commentaire, soyez compréhensifs).
    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    /** Une personne. */
    class Personne
    {
    /** Le nom de la personne. */
    // ->
    // ici ajout de final, MAIS PAS DE STATIC !
    //
    private final String m_szNom;
     
       /** Construire une personne qui a un nom. */
       public Personne(String szNom) {
    //->
    // remplacer :
    //
    // setNom(szNom);
    // par :
     m_szNom = szNom;
    // le compilateur contrôle que l'on initialise 
    // dans le constructeur toutes les variables "final".
     
    }
     
       /** Renvoyer le nom de la personne. */
    // ->
    // ceci reste permis.
    //
       public String getNom() {return(m_szNom);}
     
       /** Fixer le nom de la personne. */
       public void setNom(String szNom) {
    // ->
    // Ceci devient interdit par le compilateur.
    //
    m_szNom = szNom;};
    }
    De plus avec ce genre de construction la machine virtuelle optimise la vitesse et la mémoire. Donc moralité : JAVA C'EST MIEUX. Dont acte on le savait déjà. Mais on a eu peur.
    Mieux que Google, utilisez Sur Java spécialisé sur la plate-forme java !
    Pour réaliser vos applications Java dans le cadre de prestations, forfait, conseil, contactez-moi en message privé.

  12. #12
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    605
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 605
    Points : 670
    Points
    670
    Par défaut
    Oui, mais comment pourrais-tu alors utiliser deux instances de ta personne, l'une modifiable et l'autre non?

    Car ce que je veux me permettre de faire, c'est ceci, à partir d'une unique définition de classe.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Personne p1 = new Personne("Rébus");
    const Personne p2 = new Personne("Charade");

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    p1.setNom("Devinette");
    sera possible.

    mais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    p2.setNom("Plaisantin");
    sera interdit.

  13. #13
    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 grunt2000
    Intérêt? Cela évite de créer une classe immutable
    C'est un point de vue... L'immuabilité a également ses avantages (et le risque d'erreur est également présent avec le const, même si le compilateur peut générer des erreurs dans certains cas).

    Il s'agit juste d'une approche différente du même problème (mais je ne dis pas qu'une est meilleure que l'autre).


    Citation Envoyé par grunt2000
    Je ne pense pas que la redéfinition d'une méthode permettrait d'oublier son mot-clé. Il suffit d'écrire le compilateur et la JVM d'une manière qui convient.
    Ce n'est pas au niveau du compilateur que cela pose problème, mais au niveau de toutes les applications existantes...
    Logiquement le compilateur interdit d'appeler des méthodes non-const depuis des méthodes const...

    Prenons l'exemple de HashMap. On est d'accord qu'un grand nombre de ses méthodes devraient être const (isEmpty(), size(), etc...), alors que d'autres ne le devraient pas (add(), remove(), etc...).

    Or, afin de gérer un cache, j'ai justement une classe qui hérite de HashMap et qui revérifie la validité de la Map avant chaque action. Donc le méthode isEmpty() peut aboutir à une modification de ma Map... et donc elle casserait le principe du const et donc mon code ne compilerait plus...

    La compatibilité est cassé !



    Citation Envoyé par grunt2000
    C'est un travail certainement fastidieux pour Sun, mais à tout prendre, je pense, moins que celui d'avoir mis en place les génériques.
    La mise en place des Generics est loin d'être complète ! Elle a princiapelement été mise en place dans l'API de Collection et de Reflection (a moindre envergure). Il y a en particulier une grosse demande pour intégrer les Generics à Swing...

    Mais surtout les Generics conservent la compatibilité

    a++

  14. #14
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Citation Envoyé par grunt2000
    p1.setNom("Devinette"); sera possible.

    mais
    p2.setNom("Plaisantin"); sera interdit.
    C'est là toute la faille...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Personne p1 = new Personne();
    const Personne p2 = new Personne();
     
    p1.setNom("Devinette"); //ok
    //p2.setNom("Plaisantin"); // ne compile pas
    p1 = p2;
    p1.setNom("Plaisantin"); //ok
    //p2 a été modifié...

  15. #15
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    605
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 605
    Points : 670
    Points
    670
    Par défaut
    Non, ne t'inquiètes pas. L'affectation p1 = p2 est interdite également.

    Tu ne peux pas affecter un objet constant à une référence se déclarant porteuse d'un objet non constant.

  16. #16
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Citation Envoyé par grunt2000
    Non, ne t'inquiètes pas. L'affectation p1 = p2 est interdite également.

    Tu ne peux pas affecter un objet constant à une référence se déclarant porteuse d'un objet non constant.
    OK, et donc pour les mêmes raisons, p2 = p1 est interdite aussi...

    Donc const Personne n'est pas compatible avec Personne.

    Donc si tu as une méthode, faisons simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public static void afficher(Personne personne) {...}
    Tu n'as pas le droit de faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    const Personne p = new Personne();
    //afficher(personne); //interdit

  17. #17
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    605
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 605
    Points : 670
    Points
    670
    Par défaut
    Non, l'inverse n'est pas vrai.

    avec:
    const X a;
    X b;

    Il t'est 'interdit d'écrire:
    b = a; // Violation de la constance de a.

    mais pas:
    a = b;

    Tu peux affecter un objet non const à un pointeur const. Mais à travers ce pointeur const, tu ne pourras plus jamais le modifier.

    Ce lien parle du "const-correctness" dans les langages: http://en.wikipedia.org/wiki/Const.
    Voir la section final in Java en particulier. Ils ont l'air plus pessimistes sur son implémentation future.

  18. #18
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Citation Envoyé par grunt2000
    Non, l'inverse n'est pas vrai.

    avec:
    const X a;
    X b;

    Il t'est 'interdit d'écrire:
    b = a; // Violation de la constance de a.

    mais pas:
    a = b;

    Tu peux affecter un objet non const à un pointeur const. Mais à travers ce pointeur const, tu ne pourras plus jamais le modifier.

    Ce lien parle du "const-correctness" dans les langages: http://en.wikipedia.org/wiki/Const.
    Voir la section final in Java en particulier. Ils ont l'air plus pessimistes sur son implémentation future.
    Tu peux casser la propriété dans les 2 sens.
    Le premier sens je l'ai montré dans le post précédent.
    Le second sens (il suffit d'inverser le sens d'affectation):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Personne p1 = new Personne();
    const Personne p2 = new Personne();
     
    p1.setNom("Devinette"); //ok
    p2 = p1;
    //p2.setNom("Plaisantin"); // ne compile pas
    p1.setNom("Plaisantin"); //ok
    //p2 a été modifié...
    (ce qui importe c'est que tu peux avoir la même référence par p1 et par p2, que ça soit p1 <- p2 ou p2 <- p1)

  19. #19
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    605
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 605
    Points : 670
    Points
    670
    Par défaut
    Oui, absolument!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Personne p1 = new Personne();
    const Personne p2 = new Personne();
    à partir du moment où il existe une variable autonome p1 qui se balade, et que p2 fait une simple référence à p1, si p1 est modifié, p2 le sera aussi.
    Il n'y a pas de magie dans ce cas-là: aucun moyen de l'éviter...

    En revanche, en manipulant p2 tu ne pourras rien modifier.


    C'est comme si je te donne un accès en lecture à mon compte en banque. Tu ne peux pas verser ou retirer de l'argent dessus.
    Mais si moi, dans le même temps, je conserve une autre référence dessus - elle modifiable - et que j'y mets ou que j'en retire de l'argent, eh bien nécessairement, tu verras les sommes évoluer dessus... alors que tu as un pointeur const!
    Mais l'important pour moi, c'aura été qu'en te donnant un accès const à mon compte en banque je serai sûr que toi tu ne pourras pas le modifier!

    const, ce n'est pas forcément la garantie qu'un objet garde la même valeur (ce serait trop complexe à vérifier), c'est garantir que l'on ne peut pas, soi, le modifier dans un certain périmètre.

  20. #20
    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 grunt2000
    Ce lien parle du "const-correctness" dans les langages: http://en.wikipedia.org/wiki/Const.
    Voir la section final in Java en particulier. Ils ont l'air plus pessimistes sur son implémentation future.
    La RFE sur const a en effet été fermé : Java should support const parameters (like C++) for code maintainence



    Et en même temps une simple interface peut amplement suffire pour "simuler" le const, par exemple dans ton cas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public interface ConstPersonne {
    	public String getNom();
    }
    Qu'il suffit ensuite de faire implémenter par ta classe :
    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    /** Une personne. */
    class Personne implements ConstPersonne {
    	/** Le nom de la personne. */
    	// ->
    	// ici ajout de final, MAIS PAS DE STATIC !
    	//
    	private String m_szNom;
     
    	/** Construire une personne qui a un nom. */
    	public Personne(String szNom) {
    		// ->
    		// remplacer :
    		//
    		// setNom(szNom);
    		// par :
    		m_szNom = szNom;
    		// le compilateur contrôle que l'on initialise
    		// dans le constructeur toutes les variables "final".
     
    	}
     
    	/** Renvoyer le nom de la personne. */
    	// ->
    	// ceci reste permis.
    	//
    	public String getNom() {
    		return (m_szNom);
    	}
     
    	/** Fixer le nom de la personne. */
    	public void setNom(String szNom) {
    		// ->
    		// Ceci devient interdit par le compilateur.
    		//
    		m_szNom = szNom;
    	};
    }
    Ce qui revient au même comportement que le const du C++ :
    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 Essai
    {
    /** Un monsieur 'const'. */
    private ConstPersonne monsieur = new Personne("Remulus");
     
       /** Un essai. */
       public void unEssai()
       {
          System.out.println("Avant: " + monsieur.getNom());
          monsieur.setNom("Rébus"); // ERREUR DE COMPILATION
          System.out.println("Après: " + monsieur.getNom());
       }
     
       /** Lancement de l'essai. */
       public static void main(String[] args)
       {
          new Essai().unEssai();
          System.exit(0);
       }
    }
    a++

Discussions similaires

  1. Réponses: 10
    Dernier message: 23/10/2009, 10h04
  2. Réponses: 6
    Dernier message: 06/08/2009, 15h22
  3. Réponses: 4
    Dernier message: 25/11/2007, 22h30
  4. Réponses: 5
    Dernier message: 07/09/2007, 18h23
  5. mandriva est il disponible dans sa version finale ?
    Par kerkennah dans le forum Mandriva / Mageia
    Réponses: 7
    Dernier message: 25/05/2007, 23h37

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