2013-01-08 76 views
3

,我發現了一些Android的代碼(link):空吸來修改參數

public void getSize(Point outSize) { 
     synchronized (this) { 
      updateDisplayInfoLocked(); 
      mDisplayInfo.getAppMetrics(mTempMetrics, mCompatibilityInfo); 
      outSize.x = mTempMetrics.widthPixels; 
      outSize.y = mTempMetrics.heightPixels; 
     } 
    } 

而只是想知道 - 是什麼讓這片筆者來實現它在一個這樣的方式? (爲什麼它會修改參數而不是返回新對象?Get-methods通常是啞巴,有返回值,並且不會修改參數。我錯了嗎?)

我可以從我的頂部獲得的唯一原因頭是 - 效率。此方法的用戶可以控制創建的Point對象的數量。但是設計這樣的API是否是一個好習慣?

UPD:

我會實現它是這樣的(或類似的水木清華):

public Point getSize() { 
     Point outSize = new Point(); 
     synchronized (this) { 
      updateDisplayInfoLocked(); 
      mDisplayInfo.getAppMetrics(mTempMetrics, mCompatibilityInfo); 
      outSize.x = mTempMetrics.widthPixels; 
      outSize.y = mTempMetrics.heightPixels; 
     } 
     return outSize; 
    } 
+0

查看代碼;如果他們不使用這種方法,則會創建3個新對象。兩個用於''getAppMetrics''(嗯,這是使用單個get返回兩個參數的唯一方法)。和一個Point對象。我個人認爲他們做了正確的設計選擇。 – harism

+0

@harism,我添加了另一段代碼 - 只是一個對象,但現在看起來更加正常。不是嗎? –

+0

''mDisplayInfo.getAppMetrics''也是一個無效的getter。一旦你用一個返回新對象的getter替換它,你會發現回收在某些情況下是一個好習慣。 – harism

回答

3

如果這種方法被稱爲很多,刪除不必要的對象創建可以顯着提高性能。當你開始研究被調用的低級代碼和方法時,你就開始進行這種優化。

getSize()這樣的方法的問題是,你真的想返回一個原語。如果getSize()返回int這不會是一個問題。在這種情況下,傳遞給用作「輸出參數」的方法的參數很常見。

在J2ME中,我們一直都在做這種事情。特別是對於返回x/y座標。在這種情況下,你有2個選項不會導致對象的創建:

  1. 創建2種方法:int getX()int getY()
  2. 創建寫入X和Y座標成這樣傳遞的參數一個方法: void getXY(int[] coords)

在第二種方法中,呼叫者分配一個int[2]陣列一次(可能靜態),然後getXY()方法可以反覆使用相同的數組,以通過周圍的座標被調用。

+0

解決方案1(2個getter)可能會在多線程程序中產生問題:如果在調用getX和getY之間的點發生變化,您將得到一個混合了2個點的點... – assylias

+0

@assylias正好!所以你可能需要同步包含2個方法調用的塊。不僅如此,而且必須進行2次方法調用以獲得2個座標也是低效的。第二種解決方案是我們通常使用的解決方案(d)。 –

2

的原因是效率。按照寫入方式,此方法的用戶可以回收點實例並避免分配內存。該方法可能經常用於draw視圖代碼,在這裏重要的是要儘可能快地獲得流暢的UI體驗。

分配新對象也意味着GC必須更頻繁地踢。

2

正如其他人已經注意到的那樣,正如您所懷疑的那樣,作者可能以這種方式提高效率。

Java約定說名爲getXXX的方法應該不帶參數並返回一個值。
吸氣劑也應該最好沒有副作用。

他應該給這個方法一個不同的名字。