2017-04-07 36 views
3

鑑於下面的示例代碼是否有初始化total的方法,以便我在以後使用它時不必執行空檢查。我無法將該值傳遞給構造函數。初始化WeakReference對象以避免空檢查

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嗎?還是違背了類的目的?

感謝

編輯

感謝所有的反饋。

  • 浮點數的使用是爲了簡化問題,但我可以完全理解這種困惑。實際被弱引用持有的對象是Android佈局中的一個視圖,並且此類位於活動生命週期之外。其被評估
  • 聲明「這行不通」以前
  • total.get()應分配給本地值有關:

total.get() == null評估爲false與this.total = new WeakReference<>(null); 初始化後我現在明白這個陳述是不正確的。這將評估爲真。不過,我認爲最好不要將它初始化爲null,並在訪問之前檢查null條件。

+3

你是什麼意思,它在ctor中初始化它不起作用? –

+0

您似乎在這裏提出了多個問題。一個關於避免空檢查,另一個關於在空/釋放狀態下初始化。 –

+2

爲什麼?爲什麼使用'WeakReference'?爲什麼使用'Float'?爲什麼不是'浮動'? – EJP

回答

7

您可以初始化它是這樣的:

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

現在引用本身永遠不會爲空,但它是get方法不會返回null。新calculatePercentage方法
例子:

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

    return count/totalF; 
} 

然而
在大多數情況下,它使非常毫無意義的使用WeakReference<Float>。爲什麼不使用原始的float?或者如果你真的想要一個Float對象。因爲什麼時候Float對象真的被垃圾收集?我認爲這隻會導致狀態不一致,很難追蹤錯誤。

+0

實際對象將在哪裏包裝在WeakReference中。我只能看到'新的WeakReference <>(null);' –

+0

@ nits.kk它將通過給'total'分配一個新的WeakReference來設置。這個問題在他的'setWidget(Float total)'方法中完成。 – RobCo

+0

yups是正確的。你現在有一個upvote :) –

5

使用WeakReference您必須始終在使用前檢查空檢查。假設存在一個對象A,其存在依賴於其他上下文狀態。

如果這樣的對象被傳遞給某些未知這些上下文狀態的類,那麼它總是最好傳遞包裝在WeakReference的對象中的對象。當對這樣的對象的強引用數量變爲0時,在執行下一個垃圾收集器週期時,對象被垃圾收集。此時WeakReference的對象將在對其調用get()時開始給出空值。這是使用類(不知道上下文狀態)對象的生命期結束的信號。

在使用它之前,最好的方法是將對象存儲在本地變量中(調用get()後),檢查是否爲空檢查然後使用它。

即使您已經檢查了不符合條件的weakReference.get()也不意味着它不能爲空。您需要將get()返回的對象存儲在局部變量中,檢查它是否爲空,然後使用。 請記住不要將對象(由get()返回)作爲實例變量存儲,因爲它會創建對該對象的強引用。只需創建局部變量,不要將這些局部變量傳遞給其他方法。只要在那裏使用它們,讓它們隨着範圍的結束而死亡。

可以使用WeakReferencenew WeakReference<strongReferenceOfSomeObject>())的對象作爲方法參數來包裝和傳遞對象。如果您將其作爲方法參數或構造函數參數傳遞給不知道上下文狀態更改(可能決定對象生命期)的類,則不應將其分配給實例變量。如果需要將其分配給實例變量,則只能將其存儲爲WeakReference

多參考在https://docs.oracle.com/javase/7/docs/api/java/lang/ref/WeakReference.html

附:對於Float這可以很容易地使用float來解決,而不是將Float的對象包裝在WeakReference中。您所包含的代碼不需要WeakReference。我上面的答案旨在提供一般的高層次基礎知識。

+0

如果'total'可以在calculatePercentage()調用之間變化,則OP的代碼可能需要WeakReference。然後calculatePercentage方法將始終使用總數的當前值。 (但在這種情況下,我不認爲WeakReference是正確的,也許只是一個簡單的參考。) –