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 :

[Langage] Tableaux en final et modification


Sujet :

Langage Java

  1. #1
    Membre émérite
    Avatar de mavina
    Homme Profil pro
    Développeur Java
    Inscrit en
    Octobre 2004
    Messages
    1 812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2004
    Messages : 1 812
    Points : 2 411
    Points
    2 411
    Par défaut [Langage] Tableaux en final et modification
    Coucou,

    Je suis tombé sur un "bug" bizarre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class Test
    {
    	public final static int[] temp = { 0, 0, 0};
     
    	public static void main(String[] args)
    	{
    		temp[1] = 2;
    		System.out.println(temp[1]);
    	}
    }
    me renvoie 2 dans la console... Or le tableau est déclaré en final, on n'est pas censé pouvoir le modifier...

    Quelqu'un a une info là dessus ? C'est un bug référencé ?

    F.
    Développeur Java / Flex à Shanghai, Chine
    mes publications
    Mon dernier tutoriel : Messages Quit IRC : explications

    La rubrique IRC recrute des redacteurs : contactez moi

    Ce flim n'est pas un flim sur le cyclimse. Merci de votre compréhension.[/SIZE]

  2. #2
    Membre confirmé Avatar de Jabbal'H
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2004
    Messages
    403
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

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

    Informations forums :
    Inscription : Octobre 2004
    Messages : 403
    Points : 580
    Points
    580
    Par défaut
    c'est pas un bug, enfin à ma connaissance. Si je ne dis pas de bétise, ce doit être le même principe qu'en c, en c un tableau est toujours passé par référence dans une méthode par exemple.
    Qu'on me corrige si je m'égare.
    Grosso modo si tu faisait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     final int[] test = null;
    Déjà ca sert à rien :d, mais tu ne pourrais pas faire de new.

    c'est la meme chose qu'avec un ArrayList par ex
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     final ArrayList<String> liste = new ArrayList<String>();
    liste.add("coucou");
    Si je ne m'abuse, ca aussi ca doit marcher.
    " Je préfère comprendre les gens qui ne me comprennent pas "

  3. #3
    Expert éminent
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Points : 7 679
    Points
    7 679
    Par défaut
    Bonjour,
    Non, ce n'st pas un bug: le final ici veut dire que la référence temp ne peut pas être changé pour pointer vers un autre tableau par exemple. Mais tu peux faire ce que tu veux avec les données pointés par cette référence.

    C'est de même pour les objets:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    class Person {
      private String name;
     
      //getter + setter
    }
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    final Person p = new Person("djo");
    p.setName("mos"); //Ok !
    p = null; // Nop, ça passe po

  4. #4
    Membre averti

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2008
    Messages
    85
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Avril 2008
    Messages : 85
    Points : 355
    Points
    355
    Par défaut
    Extrait du site : http://www.ethnoinformatique.fr/mod/...ew.php?id=1078

    Le caractère final peut être attribué à une variable objet, auquel cas on comprendrait au premier abord que l'objet est constant.

    Cependant la question se pose : Est-ce la référence qui est constante, ou sont-ce les membres qui sont figés ?

    Le Java reste cohérent en définition à ce niveau : c'est bien la référence objet qui est finale, c'est à dire qu'il sera impossible de lui attribuer un autre objet que celui qui est fourni par l'initialiseur statique au moment de la déclaration de la variable.

    On peut donc modifier les valeurs des membres d'un objet final.
    conclusion :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    public class Test
    {
     
    	public final static int[] temp = {0, 0, 0};
     
    	public static void main(String[] args)
    	{
    		temp[1] = 2;	//OK, on modifie la valeur
    		temp = new int[3];	//KO, temp est static
    		System.out.println(temp[1]);
    	}
    }

  5. #5
    Membre émérite
    Avatar de mavina
    Homme Profil pro
    Développeur Java
    Inscrit en
    Octobre 2004
    Messages
    1 812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2004
    Messages : 1 812
    Points : 2 411
    Points
    2 411
    Par défaut
    Donc c'est moi qui ai mal compris le final : on déclare la référence en final mais on peut modifier l'objet référencé.

    Alors comment créer un tableau qui ne peut pas être modifié ?

    F.
    Développeur Java / Flex à Shanghai, Chine
    mes publications
    Mon dernier tutoriel : Messages Quit IRC : explications

    La rubrique IRC recrute des redacteurs : contactez moi

    Ce flim n'est pas un flim sur le cyclimse. Merci de votre compréhension.[/SIZE]

  6. #6
    Expert éminent
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Points : 7 679
    Points
    7 679
    Par défaut
    Hum ... pas possible ça, à ma connaissance.

    Par contre, c'est faisable pour les collections:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    List<String> list = Arrays.asList("chaine", "de", "chars");
    Collection<String> finalList = Collections.unmodifiableCollection(list);
    finalList.add("test");//=>UnsupportedOperationException
    finalList.remove("de");//=>UnsupportedOperationException

  7. #7
    Membre émérite
    Avatar de mavina
    Homme Profil pro
    Développeur Java
    Inscrit en
    Octobre 2004
    Messages
    1 812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2004
    Messages : 1 812
    Points : 2 411
    Points
    2 411
    Par défaut
    Citation Envoyé par djo.mos Voir le message
    Hum ... pas possible ça, à ma connaissance.

    Par contre, c'est faisable pour les collections:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    List<String> list = Arrays.asList("chaine", "de", "chars");
    Collection<String> finalList = Collections.unmodifiableCollection(list);
    finalList.add("test");//=>UnsupportedOperationException
    finalList.remove("de");//=>UnsupportedOperationException

    LE probleme étant que je programme en javaME donc pas de collections (enfin si, la classe Vector mais elle est si couteuse qu'on ne l'utilise quasiment jamais)...
    Développeur Java / Flex à Shanghai, Chine
    mes publications
    Mon dernier tutoriel : Messages Quit IRC : explications

    La rubrique IRC recrute des redacteurs : contactez moi

    Ce flim n'est pas un flim sur le cyclimse. Merci de votre compréhension.[/SIZE]

  8. #8
    Expert éminent
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Points : 7 679
    Points
    7 679
    Par défaut
    Peut être en faisant une sorte de wrapper tout mince autour des arrays ?

  9. #9
    Membre expérimenté Avatar de herve91
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 282
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 282
    Points : 1 608
    Points
    1 608
    Par défaut
    Oui, tout à fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class Wrapper {
      Object[] t;
      public Wrapper(Object t[]) {
        this.t = (Object[]) t.clone();
      }
     
      public Object get(int i) {
        return t[i];
      }
    }
    et les classes équivalentes pour des tableaux de type primitif (int, long, ...)

  10. #10
    Expert éminent
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Points : 7 679
    Points
    7 679
    Par défaut
    Faut juste ajouter un attribut boolean readOnly et un test sur sa valeur dans la méthode set ... cet attribut doit être positionanble selement dans le constructeur.

  11. #11
    Membre expérimenté Avatar de herve91
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 282
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 282
    Points : 1 608
    Points
    1 608
    Par défaut
    Citation Envoyé par djo.mos Voir le message
    Faut juste ajouter un attribut boolean readOnly et un test sur sa valeur dans la méthode set ... cet attribut doit être positionanble selement dans le constructeur.
    Il n'y a pas de méthode set. Ce qui fait que dès la compilation, on ne peut pas écrire de code modifiant le tableau (cf. par exemple Collections.unmodifiableCollection() qui fait la vérification à l'exécution)

  12. #12
    Membre averti Avatar de Tux++
    Étudiant
    Inscrit en
    Avril 2008
    Messages
    281
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2008
    Messages : 281
    Points : 379
    Points
    379
    Par défaut
    petite question,

    pourquoi chercher à rendre ton tableau immutable dans la classe que tu crées?

    je m'explique, si c'est un package à importer et que tu ne veux pas que ceux qui l'utilisent puissent modifier le tableau à l'appel du package, il suffit de déclarer ton attribut en private ou protected, il ne sera alors modifiable que dans la classe que toi-même tu as crée et donc pas de soucis.

    en fait je ne vois pas dans quel tu aurais besoin qu'il ne soit pas modifiable en interne?
    Certified Oracle Advanced PL/SQL Professional
    Certified Oracle APEX Expert
    Certified Oracle SQL Expert

  13. #13
    Expert éminent
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Points : 7 679
    Points
    7 679
    Par défaut
    Citation Envoyé par herve91 Voir le message
    Il n'y a pas de méthode set. Ce qui fait que dès la compilation, on ne peut pas écrire de code modifiant le tableau (cf. par exemple Collections.unmodifiableCollection() qui fait la vérification à l'exécution)
    , pardon, je n'ai fait que survoler ton exemple.
    En fait, ce que tu proposes est une version immutable du wrapper.
    Moi, je pensais plutôt à un wrapper générique, qui peut être mutable ou immutable, le tout contrôlé par l'attribut readOnly dès sa construction.

  14. #14
    Membre expérimenté Avatar de herve91
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 282
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 282
    Points : 1 608
    Points
    1 608
    Par défaut
    Citation Envoyé par djo.mos Voir le message
    Moi, je pensais plutôt à un wrapper générique, qui peut être mutable ou immutable, le tout contrôlé par l'attribut readOnly dès sa construction.
    Oui, il suffit d'étendre Wrapper en MutableWrapper et d'ajouter l'attribut readOnly et la méthode set.

  15. #15
    Membre émérite
    Avatar de mavina
    Homme Profil pro
    Développeur Java
    Inscrit en
    Octobre 2004
    Messages
    1 812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2004
    Messages : 1 812
    Points : 2 411
    Points
    2 411
    Par défaut
    Citation Envoyé par Tux++ Voir le message
    petite question,

    pourquoi chercher à rendre ton tableau immutable dans la classe que tu crées?

    je m'explique, si c'est un package à importer et que tu ne veux pas que ceux qui l'utilisent puissent modifier le tableau à l'appel du package, il suffit de déclarer ton attribut en private ou protected, il ne sera alors modifiable que dans la classe que toi-même tu as crée et donc pas de soucis.

    en fait je ne vois pas dans quel tu aurais besoin qu'il ne soit pas modifiable en interne?
    C'est simple, avant la compilation j'ai un preprocess qui remplace mes constantes dans le code pour faire le moins d'appel possible et de liens, et comme mon tableau est un tableau de coordonnées...

    F.
    Développeur Java / Flex à Shanghai, Chine
    mes publications
    Mon dernier tutoriel : Messages Quit IRC : explications

    La rubrique IRC recrute des redacteurs : contactez moi

    Ce flim n'est pas un flim sur le cyclimse. Merci de votre compréhension.[/SIZE]

  16. #16
    Membre averti Avatar de Tux++
    Étudiant
    Inscrit en
    Avril 2008
    Messages
    281
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2008
    Messages : 281
    Points : 379
    Points
    379
    Par défaut
    ok, alors je vois, je pensais juste à un point de vue interne, merci
    Certified Oracle Advanced PL/SQL Professional
    Certified Oracle APEX Expert
    Certified Oracle SQL Expert

Discussions similaires

  1. Réponses: 2
    Dernier message: 20/05/2007, 18h22
  2. Réponses: 2
    Dernier message: 06/04/2006, 14h42
  3. [langage] erreurs utilisation tableaux 2 dimensions
    Par drosof dans le forum Langage
    Réponses: 11
    Dernier message: 01/07/2003, 11h44
  4. [langage] Date de modification d'un fichier
    Par Cyspak dans le forum Langage
    Réponses: 2
    Dernier message: 24/06/2003, 15h49
  5. Réponses: 6
    Dernier message: 04/04/2003, 15h28

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