初始化WeakReference对象以避免空检查

run*_*ase 6 java weak-references

鉴于以下示例代码,有一种初始化方法total,以便我在以后使用它时不必进行空检查.我无法将值传递给构造函数.

public class SampleCode 
{

    private WeakReference<Float> total;

    public SampleCode() {
    }

    public void setWidget(Float total) {
        this.total = new WeakReference<>(total);
    }

    public float calculatePercentage(Float count) {
        if (total == null) {
            return -1;
        }
        if (total.get() == null) {
            return -1;
        }

        return count / total.get();
    }
}
Run Code Online (Sandbox Code Playgroud)

我想在构造函数中做这样的事情:

this.total = new WeakReference<>(null);
Run Code Online (Sandbox Code Playgroud)

但这不起作用.我可以在已发布状态下初始化WeakReference,还是违反了类的目的?

谢谢

编辑

感谢所有的反馈.

  • 浮动的使用是为了简化问题,但我可以完全理解这种混淆.弱引用实际上持有的对象是Android布局中的视图,此类存在于活动生命周期之外.
  • 在计算之前,应将total.get()分配给本地值
  • 声明"这不起作用"与以下内容有关:

total.get() == null在初始化之后评估为false this.total = new WeakReference<>(null); 我现在明白该陈述是不正确的.这将评估为真.但是我认为最好不要将它初始化为null并在访问之前检查null条件.

Rob*_*bCo 10

您可以像这样初始化它:

private WeakReference<Float> total = new WeakReference<>(null);
Run Code Online (Sandbox Code Playgroud)

现在引用本身永远不会为null,但它的get方法确实返回null.
新的calculatePercentage方法示例:

public float calculatePercentage(Float count) {
    Float totalF = total.get();
    if(totalF == null)
        return -1;

    return count / totalF;
}
Run Code Online (Sandbox Code Playgroud)

然而,
在大多数情况下,这让非常毫无意义的使用WeakReference<Float>.为什么不直接使用原语float?或者,如果你真的想要一个Float对象.因为什么时候Float对象真的会被垃圾收集?我认为这只会导致状态不一致并且很难跟踪错误.


nit*_*.kk 7

使用后WeakReference,必须始终在使用前检查空检查.假设存在一个Object,A其存在取决于其他一些上下文状态.

如果将这样的对象传递给某些不知道那些上下文状态的类,则总是更好地传递包装在对象中的对象WeakReference.随着对该对象的强引用的数量变为0,在执行下一个垃圾收集器循环时,该对象被垃圾收集.此时,对象 WeakReferenceget()在其上调用时开始给出null .这是对象的生命周期结束的使用类(不知道上下文状态)的信号.

在使用它之前,最好的方法是将对象存储在局部变量中(在调用之后get()),检查空值检查然后使用它.

即使你已经检查了不是因为条件而weakReference.get()不是暗示它不能为下一行的null.您需要将返回的对象存储get()在局部变量中,检查它是否为null然后使用.请记住,不要将对象(返回者get())存储为实例变量,因为它将创建对对象的强引用.只需创建局部变量,不要将这些局部变量传递给其他方法.只要在那里使用它们,让它们在范围结束时死亡.

您可以使用WeakReference(new WeakReference< strongReferenceOfSomeObject >())的对象作为方法参数来包装和传递对象.如果将其作为方法参数或Constructor参数传递给不知道上下文状态更改(可能决定对象生命周期)的类,则不应将其分配给实例变量.如果需要将其分配给实例变量,则只能将其存储为WeakReference仅.

更多信息,请访问https://docs.oracle.com/javase/7/docs/api/java/lang/ref/WeakReference.html

PS为此Float可以很容易地解决使用float而不是包装对象的Float问题WeakReference.您不需要WeakReference包含有问题的代码.我上面的回答旨在提供一般的高级别基本承诺WeakReference.