未更新Java WeakHashMap引用

未更新Java WeakHashMap引用,java,weak-references,weakhashmap,Java,Weak References,Weakhashmap,在下面的代码中,我创建了一个Pen对象,并将其颜色初始化为白色。在Pen的构造函数中,将字段“penColor”设置为传递给构造函数的值后,我更新了一个全局静态弱hashmap,其中键是“this pointer”——在我的例子中是Pen,值是另一个weakhashmap,其键是字符串“penColor”其值是对penColor成员字段的引用 接下来,我的代码通过调用画笔的setColor函数来更新画笔的颜色。我本以为在这次更新之后,如果我在weakhashmap中查找Pen对象的颜色字段,它会

在下面的代码中,我创建了一个Pen对象,并将其颜色初始化为白色。在Pen的构造函数中,将字段“penColor”设置为传递给构造函数的值后,我更新了一个全局静态弱hashmap,其中键是“this pointer”——在我的例子中是Pen,值是另一个weakhashmap,其键是字符串“penColor”其值是对penColor成员字段的引用

接下来,我的代码通过调用画笔的setColor函数来更新画笔的颜色。我本以为在这次更新之后,如果我在weakhashmap中查找Pen对象的颜色字段,它会反映新的颜色,但它不会。有人能解释这是为什么吗

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;

    }

}
package-weakhashmaptest;
导入java.awt.Color;
导入java.util.WeakHashMap;
导入java.util.Iterator;
公共班机{
静态WeakHashMap ownerMap=新的WeakHashMap();
公共静态void main(字符串[]args){
钢笔r=新钢笔(颜色为白色);
迭代器i=ownerMap.keySet().Iterator();
while(i.hasNext()){
对象键=i.next();
System.out.println(“\telement的hashmap是:”+ownerMap.get(key));
}
r、 设置颜色(颜色为黑色);
gc();
i=ownerMap.keySet().iterator();
while(i.hasNext()){
对象键=i.next();
System.out.println(“\telement的hashmap是:”+ownerMap.get(key));
}
}
公共静态void映射更新(对象所有者、对象引用、字符串字段\u名称){
WeakHashMap reference\u map=ownerMap.get(所有者);
如果(reference_map==null){
reference_map=new WeakHashMap();
参考地图放置(字段名称,参考);
}否则{
参考地图放置(字段名称,参考);
}
所有者映射放置(所有者,参考映射);
}
}
班笔{
彩色铅笔;
公共钢笔(c色){
铅笔色=c;
Main.mapdate(这个,penColor,penColor);
}
公共空间设置颜色(c色){
铅笔色=c;
}
}

您将颜色对象的引用放入地图,而不是笔。如果你把笔放到地图上,然后问起笔的颜色,你就会看到变化

简单地说,您所做的类似于:

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

您正在将对颜色对象的引用放入地图中,而不是笔中。如果你把笔放到地图上,然后问起笔的颜色,你就会看到变化

简单地说,您所做的类似于:

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

嗨,约翰,谢谢你的及时回复。我想我明白你的意思,但还是很难理解。钢笔的颜色和钢笔有什么不同。他们不是都是推荐人吗?请注意,我将笔作为键保留在地图中。您将笔作为键保留,但使用初始颜色作为值。这只是对一个物体的引用,而不是对“this.penColor”或类似的表达的引用。我应该把你的接受视为理解吗?如果没有,请添加更多的意见,我们可以通过这一点,你喜欢多少。我认为从等式中去掉嵌套映射是值得的,虽然它们不是真正相关的,但它们可能会让你更难思考。我知道你是对的,因为当我用你的建议更新我的示例时,它是有效的。我试图实现以下目标:在对象的构造函数中执行字节码插装。在初始化每个字段之后,我更新一个弱hashmap,它说:所有者对象是“this”,它的值是另一个hashmap,其键是字段的名称,其值是对字段的引用。现在,我希望这能给我带来以下好处:当引用被更新时,我不需要做更多的BCI,我可以依靠指向引用的映射指针。我在上一条消息中被限制为600个字符,所以我必须非常简洁。我不是要你帮我解决这个问题,只是想解释我的方法是否可行,如果不可行,为什么。我想我对这里的参考资料和指针感到困惑…嗨,约翰,谢谢你的及时回复。我想我明白你的意思,但还是很难理解。钢笔的颜色和钢笔有什么不同。他们不是都是推荐人吗?请注意,我将笔作为键保留在地图中。您将笔作为键保留,但使用初始颜色作为值。这只是对一个物体的引用,而不是对“this.penColor”或类似的表达的引用。我应该把你的接受视为理解吗?如果没有,请添加更多的意见,我们可以通过这一点,你喜欢多少。我认为从等式中去掉嵌套映射是值得的,虽然它们不是真正相关的,但它们可能会让你更难思考。我知道你是对的,因为当我用你的建议更新我的示例时,它是有效的。我试图实现以下目标:在对象的构造函数中执行字节码插装。在初始化每个字段之后,我更新一个弱hashmap,它说:所有者对象是“this”,它的值是另一个hashmap,其键是字段的名称,其值是对字段的引用。现在,我希望这能给我带来以下好处:当引用被更新时,我不需要做更多的BCI,我可以依靠指向引用的映射指针。我在上一条消息中被限制为600个字符,所以我必须非常简洁。我不是要你帮我解决这个问题,只是想解释我的方法是否可行,如果不可行,为什么。我想我对这里的引用和指针感到困惑。。。