Java 会不会有一张WeakHashMap';如果该值包含对该键的唯一强引用,则是否收集?

Java 会不会有一张WeakHashMap';如果该值包含对该键的唯一强引用,则是否收集?,java,weak-references,weakhashmap,Java,Weak References,Weakhashmap,我需要将一些数据与密钥的生命周期相关联,因此我使用的是WeakHashMap。但是,除此之外,我还需要通过其相应的值来获取一个键。创建值时,最简单的方法是保留引用: public class Key {} public class Value { final public Key key; public Value(Key k) { key = k; } } 当然,当我在程序中使用Value时,它的键不会消失。但是,如果在映射之外没有对键或其值的更多

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

public class Key {}

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

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

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

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

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

public class Value { 
  final public WeakReference<Key> key;
  public Value(Key k) {
    this.key = new WeakReference<Key>(k);
  }
}
公共类值{
最终公共引用密钥;
公共价值(k键){
this.key=新的WeakReference(k);
}
}

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

这来自
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;
    ...
}
/**
*表,根据需要调整大小。长度必须始终是2的幂。
*/
私有条目[]表;
...
私有静态类条目扩展WeakReference实现Map.Entry{
私人价值;
...
}

如您所见,
Entry
对象被地图本身强烈引用。因此,如果地图是可访问的,那么
条目也将是可访问的,因此你的
值也将是对象,还有你的键。

@biziclop同样来自Javadoc:处理这个问题的一种方法是在插入之前将值本身包装在WeakReference中,如:m.put(key,new WeakReference(Value)),然后在每次获取时展开。那就应该成功了!或者只在值对象中存储对键的弱引用。因为如果将该值包装在WR中,可能会得到一个值为alraedy collected的现有键。