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

Java 初始化WeakReference对象以避免空检查,java,weak-references,Java,Weak References,给定下面的示例代码,是否有一种初始化total的方法,这样我就不必在以后使用它时进行空检查。我无法将值传递给构造函数 public class SampleCode { private WeakReference<Float> total; public SampleCode() { } public void setWidget(Float total) { this.total = new WeakReference<

给定下面的示例代码,是否有一种初始化
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();
    }
}
公共类示例代码
{
私人财富参考总额;
公共样本代码(){
}
公共void setWidget(浮动总数){
this.total=新WeakReference(total);
}
公共浮动计算百分比(浮动计数){
如果(总计==null){
返回-1;
}
if(total.get()==null){
返回-1;
}
返回计数/total.get();
}
}
我想在构造函数中执行以下操作:

this.total = new WeakReference<>(null);
this.total=new WeakReference(null);
但这不起作用。我是否可以在已发布状态下初始化WeakReference,或者这是否违背了类的目的

谢谢

编辑

感谢所有的反馈

  • 使用float是为了简化问题,但我完全理解其中的混乱。弱引用实际持有的对象是Android布局中的视图,该类位于活动生命周期之外
  • 在计算total.get()之前,应将其赋值给一个局部值
  • “这不起作用”的声明涉及:
total.get()==null
使用
this.total=new WeakReference(null)初始化后计算为false

我现在理解这一说法是不正确的。这将评估为真。不过,我认为最好不要将其初始化为null,而是在访问之前检查null条件

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

如果这样的对象被传递给那些上下文状态未知的某个类,那么最好传递包装在
WeakReference
对象中的对象。当对此类对象的强引用数变为0时,在执行下一个垃圾回收器周期时,该对象将被垃圾回收。此时,调用
get()
时,
WeakReference
的对象将开始提供null。这是一个向使用类(不知道上下文状态)发送的信号,表示对象的生命周期已经结束

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

即使您根据
weakReference.get()
的条件检查了NOTNULL,也不意味着它在下一行不能为null。您需要将
get()
返回的对象存储在局部变量中,检查它是否为NOTNULL,然后使用记住不要将对象(由
get()
返回)存储为实例变量,因为它将创建对对象的强引用。
只需创建局部变量,不要将这些局部变量传递给其他方法。只要在那里使用它们,让它们随着范围的结束而消亡

您可以使用
WeakReference
newweakreference()
)的对象作为方法参数包装和传递对象。如果您将其作为方法参数或构造函数参数传递给不知道上下文状态更改(这可能决定对象的生命周期)的类,则不应将其分配给实例变量。如果需要将其分配给实例变量,则必须仅将其存储为
WeakReference

请参阅


p.S.对于
Float
这可以使用
Float
轻松解决,而不是在
WeakReference
中包装
Float
的对象。您不需要
WeakReference
来查看您所包含的问题代码。我以上的回答旨在提供对
WeakReference
一般用法的高层次基本理解

您可以这样初始化它:

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

在大多数情况下,使用
WeakReference
没有什么意义。为什么不直接使用原语
float
?或者如果你真的想要一个
浮动对象。因为什么时候才能真正对Float对象进行垃圾收集?我认为这只会导致状态不一致和难以跟踪bug。

在ctor中初始化它时,它不工作是什么意思?您似乎在这里问了不止一个问题。一个是关于避免空检查,另一个是关于在空/释放状态下初始化。为什么?为什么要使用
WeakReference
?为什么要使用
浮点数
?为什么不使用
float
?@运行代码库正如EJP在评论中所说的那样,对于包含的代码,您不需要WeakReference,只需使用基本float即可。但你仍然可以参考我的答案了解WeakReference@nits.kk的一般用法。为了清晰起见,我添加了一些编辑。使用Float的目的是简化代码,使其专注于如何使用空值正确初始化WeakReference。我能理解我造成的混乱。感谢您的反馈。如果调用calculatePercentage()时,
total
可能会有所不同,则OP的代码可能需要一个WeakReference。然后calculatePercentage方法将始终使用total的当前值。(但在这种情况下,我不认为WeakReference是正确的使用方法;可能只是一个简单的引用。)WeakReference将实际对象包装在哪里。我只看到
newweakreference(null)
@nits.kk将通过将新的WeakReference分配给
total
进行设置。在问题中,这是在他的
setWidget(Float-total)
方法中完成的。
public float calculatePercentage(Float count) {
    Float totalF = total.get();
    if(totalF == null)
        return -1;

    return count / totalF;
}