9

我需要将一些数据与其生命周期内的密钥相关联,因此我使用的是WeakHashMap. 但是,除此之外,我还需要通过其对应的值获取一个键。最简单的方法是在创建值时保持引用:

public class Key {}

public class Value { 
    final public Key key;
    public Value(Key k) {
        key = k;
    }
}

当然,当我Value在我的程序中使用时,它key不会消失。但是,如果在 map 之外没有更多对键或其值的引用,它会被垃圾回收吗?还是值中幸存的强引用阻止了它?

4

2 回答 2

14

不,它不会被垃圾收集,请参阅Javadoc

实现说明:WeakHashMap 中的值对象由普通的强引用保存。因此,应注意确保值对象不会直接或间接地强烈引用它们自己的键,因为这将防止键被丢弃。

正如@biziclop 所提到的,一种解决方案是在值对象中存储对键的弱引用。

public class Value { 
  final public WeakReference<Key> key;
  public Value(Key k) {
    this.key = new WeakReference<Key>(k);
  }
}
于 2011-11-08T14:43:14.083 回答
2

从实现来看,答案似乎是否定的。

这是从WeakHashMap源头:

/**
 * The table, resized as necessary. Length MUST Always be a power of two.
 */
private Entry[] table;

...

private static class Entry<K,V> extends WeakReference<K> implements Map.Entry<K,V> {
    private V value;
    ...
}

如您所见,Entry对象被地图本身强烈引用。因此,如果地图是可访问的,那么Entry您的Value对象和您的密钥也将如此。

于 2011-11-08T14:43:30.917 回答