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 :

comportement de variables statiques


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    988
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 988
    Par défaut comportement de variables statiques
    Bonjour,

    Voici le code d'une classe Animal qui contient une variable statique nomméé id, comme le précise le code ci-dessous

    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
    public class Animal{
    
    int identifiant;
    boolean male;
    int age;
    
    static int id=0;
    
    //constructeur
    Animal(boolean male1, int age1){
    this.male = male1;
    this.age= age1;
    identifiant = id;
    id++
    
    }// fin constructeur
    }// fin de classe

    D'après ce code, à chaque création d'une instance de la classe animal, la variable identifiant contiendra une valeur incrémentée de 1 donc chaque animal aura un identifiant sequentiel.

    voici un autre code qui semble contredire celui ci

    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
     
     
    public class Date{
     
    int jour;
    int mois;
    int annee;
     
    static int nb;
     
    }
    puiblic class TestStatic{
     
    public static void main(String []args){
    Date d1= new Date(1,1,2000);
    Date d2= new Date(2,2,2004);
     
    System.out.println(Date.nb);
     
    System.out.println(d1.nb);
     
    System.out.println(d2.nb);
    Date.nb=2;
     
    System.out.println(Date.nb + "  " +d1.nb +  "   " +d2.nb);
     
    d1.nb=1;
    d1.jour = 23
     
     
    System.out.println(Date.nb + "  " +d1.nb +  "   " +d2.nb);
     
    System.out.println(d1.jour+  "  "  +d2.nb );
     
    }
     
    }
    Voici le résultat obtenu
    0
    0
    0
    2,2,2
    1,1,1
    23,2

    Ces résultats ne contredisent ils pas les résultats obtenus auparavant.
    Car d'après ce nouveau code, la variable identifiant des instances de la classe Animal ne devrait elle pas contenir toujours la même valeur, puisque la valeur d'une variable statique est partagée par toutes les instances de la classe qui contient cette variable statique.
    donc si la valeur de cette varaible statique evolue, elle evolue pour toutes les instances de la classe.
    Pouvez vous me dire si quelque chose n'est pas bien compris de ma part ou si ces deux résultats sont contradictoires .

    Je vous en remercie beaucoup.

    Cordialement.

    Nathalie

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 764
    Par défaut
    Pourquoi ne pas effectuer tes tests directement sur la classe Animal ?
    Tu y verrais bien mieux...

    Citation Envoyé par harbonne Voir le message
    la variable identifiant des instances de la classe Animal ne devrait elle pas contenir toujours la même valeur, puisque la valeur d'une variable statique est partagée par toutes les instances de la classe qui contient cette variable statique.
    donc si la valeur de cette varaible statique evolue, elle evolue pour toutes les instances de la classe.
    Ce n'est pas la variable identifiant qui est statique, c'est la variable id !
    Il y a deux variables :
    - le compteur id, statique, qui est donc effectivement partagé par toutes les instances de la classe Animal, et qui est incrémenté à chaque instanciation de la classe
    - la variable identifiant, propre à chaque instance de Animal, qui prend la valeur qu'avait le compteur id au moment de l'instanciation de la classe
    Même si le compteur id est incrémenté à chaque création d'un animal, l'identifiant de chaque animal, lui, n'est pas modifié...

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    988
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 988
    Par défaut comportement de variables statiques
    Bonjour et merci de ta réponse.

    Comme tu le dis, rien ne vaut un test réél.
    C'est ce que je vais faire au plus vite pour bien comprendre ce qui se passe.

    Cordialement.
    Nathalie

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 71
    Par défaut
    Bonjour,

    Une donnée statique n'est effectivement pas liée à une instance d'une classe mais à la classe elle-même. De fait quel que soit le moyen que tu utilises pour y accéder, tu récupères la même valeur pour la bonne et simple raison que tu références la même adresse en mémoire. Concrètement, dans ton code, tu as la classe Date avec sa donnée statique nb, et les instances d1 et d2 de cette classe. Utiliser Date.nd, d1.nb ou d2.nb te donne la valeur qui est localisée dans une seule zone en mémoire ; il n'y a qu'une seule variable.

    Cette variable étant liée à la classe, il est d'ailleurs incorrect d'y accéder par le biais d'une instance. La seule expression valide dans ce cas est donc Date.nd. Les expressions d1.nb ou d2.nb ne devraient pas être utilisées. Tu peux généralement régler ton environnement de développement pour durcir tes critères de compilation et faire que ce type de manipulations soient considérées au moins comme des warnings, éventuellement comme des erreurs.

    Maintenant, dans le cadre de ta question, il faudrait donner le code complet parce qu'il manque au moins le constructeur de ta classe Date et qu'il y a des erreur syntaxiques dedans. Bon, en corrigeant ces points, on obtient:

    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
    39
    40
     
    public class TestStatic {
     
    	public static class Date{
     
    		int jour;
    		int mois;
    		int annee;
     
    		static int nb = 0;
     
    		public Date(final int jour, final int mois, final int annee) {
    			this.jour = jour;
    			this.mois = mois;
    			this.annee = annee;
    			++nb;
    		}
     
    	}
     
    	public static void main(final String []args) {
     
    		final Date d1= new Date(1,1,2000);
    		final Date d2= new Date(2,2,2004);
     
    		System.out.println(Date.nb);
    		System.out.println(d1.nb);
    		System.out.println(d2.nb);
     
    		Date.nb=2;
     
    		System.out.println(Date.nb + "  " +d1.nb +  "   " +d2.nb);
     
    		d1.nb=1;
    		d1.jour = 23;
    		System.out.println(Date.nb + "  " +d1.nb +  "   " +d2.nb);
    		System.out.println(d1.jour+  "  "  +d2.nb );
     
    	}
    }
    Et le fait est qu'avec ce code, on a pas les mêmes résultats que ceux que tu indiques. à savoir:

    2
    2
    2
    2 2 2
    1 1 1
    23 1


    ERRATUM: après relecture, je vois qu'il n'y a pas de ++nb dans ton constructeur (d'où les trois premier 2), mais ça ne change pas grand chose au propos.

    Avec en gras ce qui change entre les deux (et qui est logique). Pour obtenir tes résultats, la valeur de nb a nécessairement été modifiée entre les lignes System.out.println(Date.nb + " " +d1.nb + " " +d2.nb); et System.out.println(d1.jour+ " " +d2.nb );.

    Ci-après, je te joins un petit bout de code qui fait des manips de ce genre si tu veux faire des essais.

    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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
    public class Main {
     
    	private static final class A {
     
    		public static int count = 0;
    		private int _value;
     
    		public A(final int value) {
    			_value = value;
    			++count;
    		}
     
    		public int getValue() {
    			return _value;
    		}
     
    		public void setValue(final int value) {
    			_value = value;
    		}
     
    	}
     
    	private static final int MAX = 5;
     
    	private static void print(final List<A> as) {
     
    		System.out.println("------------------------------------------");
    		System.out.println("A.count = " + A.count);
    		System.out.println("------------------------------------------");
    		for (final A a : as)
    			System.out.println("A.count = " + A.count + ", " +
    			                   "a.count = " + a.count + ", " +
    			                   "a.getValue() = " + a.getValue());
    		System.out.println("------------------------------------------");
    		System.out.println();
     
    	}
     
    	public static void main(final String[] args) {
     
    		// Test 1: création d'instances de A
    		final List<A> as = new ArrayList<A>();
    		for (int i = 0 ; i < MAX ; ++i)
    			as.add(new A(i));
    		print(as);
     
    		// Test 2: modification de la donnée statique
    		A.count = 6;
    		print(as);
     
    		// Test 3: modification du contenu des instances
    		for (final A a : as)
    			a.setValue(a.getValue() + 1);
    		print(as);
     
    	}
     
    }
    Petit conseil enfin, je te recommande vivement, tant que tu ne maîtrises pas très clairement ce que ça signifie, de déclarer tes classes internes (comme ta classe Date) static, comme c'est fait pour la classe A ci-dessus.

    En espérant que ça t'amène des éléments de réponse.

Discussions similaires

  1. Réponses: 14
    Dernier message: 05/09/2006, 01h17
  2. [Tableaux] Probleme variable statique dans une classe
    Par Joe Le Mort dans le forum Langage
    Réponses: 7
    Dernier message: 31/08/2006, 11h35
  3. Réponses: 4
    Dernier message: 10/08/2006, 18h11
  4. Utilisation d'une variable statique
    Par kurkaine dans le forum C++Builder
    Réponses: 6
    Dernier message: 14/06/2006, 13h49
  5. Exportation de variable statique
    Par Laurent Gomila dans le forum C++
    Réponses: 16
    Dernier message: 31/08/2005, 16h32

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