19

我正在实现一些行为,这些行为有时可以从使用弱引用中受益。我希望班级的用户能够在施工时指出是否是这种情况。由于乍一看WeakReference扩展,我似乎可以做类似的事情(这是一个模型,而不是我真正想要做的事情):Reference

public class Container<T> {
    private boolean useWeakRef;
    private Reference<T> ref;

    public Container(boolean isWeak) {
        useWeakRef = isWeak;
    }

    public void store(T val) {
        if(useWeakRef) {
            ref = new WeakReference<>(val);
        } else {
            ref = new StrongReference<>(val);
        }
    }

    // May return null
    public T get() {
        return ref.get();
    }
}

但是没有StrongReference类,并且根据参考 javadocs

因为引用对象是与垃圾收集器密切合作实现的,所以这个类不能直接子类化。

所以我不能创建我自己的引用子类来持有对对象的强(即正常)引用。这似乎意味着不可能创建一个隐藏它是否使用来自调用者的弱(或软)引用的类。

我真的不明白为什么这个类不存在,一个StrongReference对象应该总是简单地从 get() 返回对象,除非 clear() 已被调用。为什么这个不见了?在某种程度上是StrongReference不一致的吗?Reference这将使构建通用引用持有者对象变得更加简单。

4

3 回答 3

4

当我需要这样做时,我只是创建了一个自定义的 Reference 接口和一个 WeakReference 的简单子类。这很烦人,但它和你能做的一样好。

public interface MyReference<T> {
  public T get();
}

public class MyWeakReference<T> extends WeakReference<T> implements MyReference<T> {
}

public class MyStrongReference<T> implements MyReference<T> {
  // obvious implementation here ...
}

更新:

澄清一下,我不知道为什么它首先没有包含在 jdk 中(我也希望它已经包含),但是,我觉得这是一个合理的解决方法。

对于那些寻求证明这个想法的人,我发现在实现自定义缓存时有必要,其中引用的强度是缓存配置的一部分。

于 2013-03-27T15:15:36.393 回答
3

您不能继承 Reference 因为它没有任何公共/受保护的构造函数。但是有一个解决方法:

class StrongReference<T> extends WeakReference<T> {
    private final T referent;

    StrongReference(T referent) {
        super(null);
        this.referent = referent;
    }

    @Override
    public T get() {
        return referent;
    }

    // implement other methods
}
于 2013-03-27T05:49:50.397 回答
1

Guava'sLocalCache使用一个StrongValueReference类来复制我想要一个StrongReference类做的事情。虽然 Guava 没有将其公开为公共类太糟糕了,但我认为这是确认这是 JDK 中缺少的功能,并且可以在必要时复制它。

也就是说,大多数需要抽象他们正在使用的引用类型的用例可能能够像我一样直接使用Guava 的Cache行为。我鼓励任何遇到这个问题的人在自己重新发明这种抽象引用行为之前探索 Guava 现有的缓存机制。

于 2015-08-24T20:41:16.447 回答