Outils pour utilisateurs

Outils du site


java:memoire

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
java:memoire [2013/11/04 13:47] – [Construction d'objets] brunojava:memoire [2013/11/04 16:11] (Version actuelle) – [Java l'amnésique] bruno
Ligne 444: Ligne 444:
 Object o1 = new Object(); Object o1 = new Object();
 Object o2 = new Animal("Serge"); Object o2 = new Animal("Serge");
-Object o3 = new Animal("Tryphon", "Cheval");+Object o3 = new Animal("Tryphon", "Pingouin");
 Object o4 = new Pingouin("Thérèse"); Object o4 = new Pingouin("Thérèse");
 </code> </code>
Ligne 478: Ligne 478:
 </code> </code>
  
 +Cette fois-ci, on utilise le constructeur de Animal. Un Animal **est un** Object, donc java va commencer par construire un Object en appelant le constructeur //Object()// hérité par Animal.
  
 +Ensuite, il va ajouter les attributs de l'instance o2 venant de Animal, et les méthodes de Animal:
 +
 +{{ :java:memoireobj2.png?600 | état de la mémoire après appel du constructeur Animal("Serge")}}
 +
 +<code java>
 +Object o1 = new Object();
 +Object o2 = new Animal("Serge");
 +Object o3 = new Animal("Tryphon", "Pingouin");
 +</code>
 +
 +On utilise maintenant le constructeur //Animal(String n, String e)//.
 +Il n'y a pas de différence avec le cas précédent. Notez cependant que la zone mémoire contenant les méthodes de Animal n'est pas dupliquée (les méthodes/comportement sont les mêmes pour toutes les instances d'Animal).
 +
 +{{ :java:memoireobj3.png?600 | état de la mémoire après appel du constructeur Animal("Tryphon", "Pingouin")}}
 +
 +<code java>
 +Object o1 = new Object();
 +Object o2 = new Animal("Serge");
 +Object o3 = new Animal("Tryphon", "Pingouin");
 +Object o4 = new Pingouin("Thérèse");
 +</code>
 +
 +Cette fois-ci, le constructeur //Pingouin(String n)// va appeler **explicitement** le constructeur //Animal(String n, String e)// qui va lui-même appeler (implicitement) le constructeur //Object()//.
 +
 +Il suffit alors de "dépiler" les appels et voici ce qu'on obtient au final en mémoire:
 +
 +{{ :java:memoireobj4.png?600 | état de la mémoire après appel du constructeur Animal("Thérèse")}}
 +
 +Vous vous rappelez du "Garbage Collector" (le ramasse-miettes en français).
 +
 +C'est le processus de java qui s'occupe de libérer la mémoire.
 +
 +La dernière figure vous permettra de bien comprendre comment il fonctionne: tant qu'une zone de la mémoire reçoit une flèche, ça veut dire qu'elle est "pointée", donc encore utilisée.
 +
 +Une zone de mémoire qui ne reçoit plus de flèche est une zone dont les données ne pourront jamais être récupérées: le garbage collector va donc pouvoir effacer cette zone, et indiquer qu'elle est libre pour une nouvelle utilisation. C'est simple avec un dessin, non?
 +
 +
 +==== Et les tableaux d'objets? ====
 +
 +Que se passe-t-il dans le cas de tableaux d'objets?
 +
 +Réfléchissez, vous avez déjà la réponse!
 +
 +===== Java l'amnésique =====
 +
 +Et pour finir, parlons des pertes de mémoires de java! Je veux parler du problème suivant:
 +
 +<code java>
 +Object o1 = new Object();
 +Object o2 = new Animal("Serge");
 +Object o3 = new Animal("Tryphon", "Pingouin");
 +Object o4 = new Pingouin("Thérèse");
 +
 +o4.jouer();
 +
 +o4.glisser();
 +</code>
 +
 +Le compilateur java nous indique deux erreurs: 
 +
 +<code>
 +TypeConstruit.java:62: error: cannot find symbol
 + o4.jouer();
 +   ^
 +  symbol:   method jouer()
 +  location: variable o4 of type Object
 +TypeConstruit.java:64: error: cannot find symbol
 + o4.glisser();
 +   ^
 +  symbol:   method glisser()
 +  location: variable o4 of type Object
 +2 errors
 +
 +</code>
 +
 +Pourtant, //o4// a été construit avec un constructeur de //Pingouin//!
 +
 +Rappelez-vous que javac n'est qu'un programme, pas toujours très intelligent donc!
 +
 +Ce que javac voit, c'est que //o4// est déclaré comme //Object//.
 +
 +Il cherche donc les méthodes //jouer()// et //glisser()// dans la zone de mémoire d'Object... et bien sûr ne les trouve pas car elles n'y sont pas!
 +
 +Pourtant, si on regarde le dernier schéma, on voit bien que ces méthodes sont chargées dans la mémoire!
 +
 +Il va donc falloir explicitement dire à Java de regarder un peu plus en détail. C'est le fameux **cast** ou **transtypage** que nous avons déjà vu avec les types primitifs, sauf que là il ne peut y avoir perte de données: soit l'opération est possible, soit elle est impossible et génerera une erreur de type //ClassCastException//.
 +
 +Nous allons donc définir une variable et lui dire de pointer dans la même zone mémoire que //o4//, en demandant à java d'étendre un peu son champ de vision, ou de //retrouver la mémoire// ;-)
 +
 +<code java>
 + Object o4 = new Pingouin("Thérèse");
 + /* ça marche pas!
 + o4.jouer();
 + o4.glisser();*/
 +
 + Animal a = (Animal)o4;
 + a.jouer();
 +
 + ((Pingouin)o4).glisser();
 +</code>
 +
 +Je vous ai mis deux manières de faire:
 +  * dans le premier cas, je déclare une variable //a//, et après j'appelle jouer();
 +  * dans le deuxième cas, je fais directement le cast sans passer par une variable: java créera une variable temporaire et appellera ensuite la méthode glisser().
 +
 +Et la question de la fin pour voir si vous avez bien compris: 
 +
 +//**"Combien d'instances ont été créées en tout dans le dernier code???"**//
 +
 +===== Codes complet des exemples =====
 +
 +Archive du code au format tar.gz : {{:java:memoire.tar.gz|code des fichiers java utilisés}}
 +
 +Vous pouvez exporter ce TP en pdf en utilisant le lien du menu de gestion de cette page (le dernier, petite icône en crayon)
  
  
  
java/memoire.1383572878.txt.gz · Dernière modification : 2013/11/04 13:47 de bruno