2009-09-18 7 views
0

Dans le code ci-dessous, je crée un objet Pen et initialise sa couleur au blanc. Dans le constructeur de Pen, après avoir mis le champ 'penColor' à la valeur passée dans le constructeur, je mets à jour un hashmap statique global que je garde là où le KEY est le 'this pointeur - dans mon cas un Pen, et le value est un autre weakhashmap dont KEY est la chaîne "penColor" et dont la valeur est une référence au champ membre de penColor.Référence Java WeakHashMap non mise à jour

Ensuite, mon code met à jour la couleur du Pen avec un appel à la fonction setColor du Pen. J'aurais pensé qu'après cette mise à jour, si je cherchais le champ de couleur de l'objet Pen dans ma carte weakhashmap, cela refléterait la nouvelle couleur, mais ce n'est pas le cas. Quelqu'un peut-il expliquer pourquoi c'est?

package weakhashmaptest; 


import java.awt.Color; 
import java.util.WeakHashMap; 
import java.util.Iterator; 

public class Main { 

    static WeakHashMap <Object, WeakHashMap>ownerMap = new WeakHashMap<Object, WeakHashMap>(); 

    public static void main(String[] args) { 

     Pen r = new Pen(Color.WHITE); 

     Iterator i = ownerMap.keySet().iterator(); 

     while(i.hasNext()) { 
      Object key = i.next(); 
      System.out.println("\telement of hashmap is : " +ownerMap.get(key)); 
     } 

     r.setColor(Color.BLACK); 

     System.gc(); 

     i = ownerMap.keySet().iterator(); 

     while(i.hasNext()) { 
      Object key = i.next(); 
      System.out.println("\telement of hashmap is : " +ownerMap.get(key)); 
     } 

    } 

    public static void mapUpdate(Object owner, Object reference, String field_name) { 

     WeakHashMap reference_map = ownerMap.get(owner); 

     if (reference_map == null) {   
      reference_map = new WeakHashMap(); 
      reference_map.put(field_name, reference); 
     } else {   
      reference_map.put(field_name, reference); 
     } 

     ownerMap.put(owner, reference_map); 

    } 

} 

class Pen { 

    Color penColor; 

    public Pen(Color c) { 

     penColor = c; 
     Main.mapUpdate(this, penColor, "penColor"); 

    } 

    public void setColor(Color c) { 

     penColor = c; 

    } 

} 

Répondre

5

Vous mettez une référence à la couleur objet dans la carte, plutôt que le Pen . Si vous mettez le Pen dans la carte, puis que vous lui demanderez la couleur du crayon ultérieurement, vous verrez le changement.

Pour le dire en termes très simplistes, ce que vous faites est semblable à:

Pen pen = new Pen(Color.WHITE); 
Color color = pen.penColor; 
pen.setColor(Color.BLACK); 
// color here still refers to Color.WHITE, not Color.BLACK. 
+0

Salut John, Merci pour la réponse rapide. Je pense que je comprends ce que vous dites, mais c'est encore difficile à digérer. En quoi la couleur de Pen est-elle différente de celle du Pen? Ne sont-ils pas tous les deux des références? Notez que je garde le stylo sur la carte, en tant que clé. –

+0

Vous conservez le stylet comme clé, mais vous utilisez la * couleur initiale * comme valeur. C'est juste une référence à un objet - ce n'est pas une référence à l'expression "this.penColor" ou quelque chose comme ça. –

+0

Dois-je accepter votre acceptation comme compréhension? Si ce n'est pas le cas, veuillez ajouter d'autres commentaires et nous pourrons en parcourir autant que vous le souhaitez. Je pense que cela vaut la peine de retirer les cartes imbriquées de l'équation - elles ne sont pas vraiment pertinentes, mais elles peuvent vous rendre la tâche plus difficile. –