Java WeakHashMap não referência a ser actualizado
-
22-07-2019 - |
Pergunta
No código abaixo eu criar um objeto Pen e inicializar a sua cor para branco. No construtor de Pen, depois de definir o campo 'pencolor' para o valor passado para o construtor, eu atualizar um hashmap fraco estática global que eu estou mantendo onde a chave é a 'este ponteiro - no meu caso, uma caneta, eo valor é outro WeakHashMap cuja chave é a cadeia "pencolor" e cujo valor é uma referência para o campo de membro pencolor.
Em seguida, o meu código atualiza a cor da caneta com uma chamada para a função setColor do Pen. Eu teria pensado que depois de esta actualização, se eu olhei para cima campo cor do objeto Pen na minha WeakHashMap, seria refletir a nova cor, mas isso não acontece. Alguém pode explicar por que isso acontece?
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;
}
}
Solução
Você está colocando uma referência ao Cor objeto no mapa, ao invés do Pen . Se você colocar o Pen para o mapa, e, então, pediu para a cor da caneta, mais tarde, você veria a mudança.
Para colocá-lo em termos muito simplistas, o que você está fazendo é semelhante a:
Pen pen = new Pen(Color.WHITE);
Color color = pen.penColor;
pen.setColor(Color.BLACK);
// color here still refers to Color.WHITE, not Color.BLACK.