2012-10-30 164 views
1

假設我想創建一個新的實例foo。Java:創建新實例

我會做這樣的:

SomeClass foo = new SomeClass(); 

現在讓我們說的對象已經到達終點(例如像在遊戲中的碰撞子彈。),並應設置,並重新初始化。要重置對象,我可以做這一點:

foo = new SomeClass(); 

或本

foo.reset(); 

注:該reset()方法只會重置從實例中的所有變量。

哪個更好的方法去(當試圖避免GC)? 第一個選項是否會創建一個新的指針?

回答

2

第一個選項創建一個新對象並將舊對象作爲垃圾收集(除非有其他實時引用)。

減少GC的一個策略是維護一個對象池。這將只是一些沒有當前使用並可供重用的對象的集合。當你完成一個對象時,調用一個將它返回給池的方法。當你需要一個新對象時,調用一個在創建一個新對象之前檢查這個對象的方法;如果池不是空的,它會從池中移除一個對象並重用它,而不是創建一個新對象。

public class SomeClass { 
    private static final int MAX_POOL_SIZE = . . .; 
    private static final ArrayList<SomeClass> pool = new ArrayList<SomeClass>(); 

    public static SomeClass getInstance() { 
     int poolSize = pool.size(); 
     if (poolSize > 0) { 
      return pool.remove(poolSize-1); 
     } 
     return new SomeClass(); 
    } 

    public void recycle() { 
     // reset any fields 
     if (pool.size() < MAX_POOL_SIZE) { 
      pool.add(this); 
     } 
    } 
    . . . 
} 

當您需要新的SomeClass時,請致電SomeClass.getInstance()。當您完成一個實例時,請將其稱爲recycle()方法。

+0

+1。你能否在實例化時使用泛型?和一個sepparated池類?我不認爲把它扔在一起是足夠乾淨的。 – Flavius

+0

@Flavius - 這有點複雜,但它可以完成。您需要擁有工廠對象或提供其他一些機制,以便在池空的情況下構建新實例。 –

0

如果你想避免GC,第二個選擇更好。其實,即使您選擇第一個選項,JVM也不會立即執行GC。當堆滿時(或者對於剛剛創建的對象不夠),它會GC。第一個創建一個新的實例,並沒有強烈的舊對象引用。所以當JVM堆滿時,它會執行GC,並且舊對象將被GCed。

此外,還有一些關於GC的內容,參考是您使用的參考類型。有四種名稱,分別是「強,軟,弱和幻影」。即使使用第二個選項,對象「foo」也可能被GCed,除非對象「foo」的引用是強烈的引用。請參閱JDK文檔以獲得有關四種參考類型的更多信息,例如ReferencePhantomSoftReferenceWeakReference