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

Initialise WeakReference object to avoid null check

鉴于下面的示例代码有一种初始化 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();
    }
}

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

this.total = new WeakReference<>(null);

但这不起作用。我可以在释放状态下初始化 WeakReference 还是违背 classes 目的?

谢谢

编辑

感谢所有反馈。

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

使用 WeakReference 时,您必须始终在使用前检查是否存在空值检查。假设有一个对象 A 其存在依赖于其他一些上下文状态。

如果这样的对象被传递给一些class,而这些上下文状态是未知的,那么传递包裹在WeakReference对象中的对象总是更好。当对该对象的强引用数变为 0 时,在执行下一个垃圾收集器周期时,该对象将被垃圾收集。此时 WeakReference 的对象将在 get() 被调用时开始给出空值。这是向 using class(不知道上下文状态)发出的信号,表明对象的生命周期已经结束。

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

即使您已经针对 weakReference.get() 的条件检查了 not null 并不意味着它不能在下一行为 null。您需要将get()返回的对象存储在一个局部变量中,检查它是否不为空然后使用。 切记不要将对象(由 get() 返回)存储为实例变量,因为它会创建对该对象的强引用。 只需创建局部变量,不要传递这些局部变量其他方法的变量。只需在那里使用它们,让它们在作用域结束时消亡。

您可以使用 WeakReference ( new WeakReference< strongReferenceOfSomeObject >() ) 的对象作为方法参数包装并传递对象。如果您将它作为方法参数或构造函数参数传递给 class 而不知道上下文状态的变化(这可能决定对象的生命周期),则不应将其分配给实例变量。如果需要将其分配给实例变量,则只能将其存储为 WeakReference

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

P.S. 对于 Float 这可以很容易地使用 float 解决,而不是将 Float 的对象包装在WeakReference。对于您包含的相关代码,您不需要 WeakReference。我上面的回答旨在提供对 WeakReference 一般用法的高级基本理解。

你可以这样初始化它:

private WeakReference<Float> total = new WeakReference<>(null);

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

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

    return count / totalF;
}

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