为什么没有StrongReference对象?

时间:2013-03-27 04:26:06

标签: java memory-management reference

我正在实现一些可能会从某些时候使用弱引用中受益的行为。我希望班级的用户能够在施工时指出是否是这种情况。由于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();
    }
}

然而,根据Reference javadocs

,没有StrongReference
  

由于引用对象是与垃圾收集器密切配合实现的,因此该类可能不会直接进行子类化。

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

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

3 个答案:

答案 0 :(得分: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中(我也希望它曾经存在),但是,我觉得这是一个合理的解决方法

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

答案 1 :(得分: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
}

答案 2 :(得分:1)

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

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