2011-08-20 118 views
4

我想要合併我的項目中的某些類。所以我不希望能夠使用新的SomeClass()實例化這些類,而是使用SomeClass.allocate()從池中獲取新項目。 我有這種類型的代碼需要合併每個類。Java:僅允許一個類實例化

public class GameObject 
{ 
    // Pooling: Provides a static method for allocation and a method for freeing 
    private static Pool<GameObject> pool = new Pool<GameObject>(); 
    public static GameObject allocate() { return pool.obtain(); } 
    public void free() { pool.free(this); } 
    ... 
} 

現在我可以禁用通過將默認構造函數實例私人的正常方式,但問題是,游泳池需要在創建時將類實例,並在池需要擴大。

是否有某種方法可以將建築限制在只有游泳池?

+0

剛剛從C++移動到java嗎?因爲這種事情是用C++完成的,有時在這個世界裏是個好主意,但在java中可能永遠不是好主意。 – Kevin

+0

我說順便說一句,因爲傳統的觀點是JVM比你做得更好。 – Kevin

+0

你可以添加代碼如何在池中添加遊戲對象 – John

回答

2

你有2個選擇,我可以看到:要麼使它成爲一個內部類的游泳池或使allocate方法包私有,並把它在同一個包池。

編輯:啊。只需將構造函數設爲私有,然後重寫Pool用來創建新實例的任何方法。作爲使用上述的幀的(粗)例如:

public abstract class Pool<T> 
{ 
    public abstract T getNewObject(); 

    public T obtain(){ return getNewObject(); } 

    public void free(T obj) {} 
} 

public class GameObject 
{ 
    // Pooling: Provides a static method for allocation and a method for freeing 
    private static Pool<GameObject> pool = new Pool<GameObject>(){ 
      public GameObject getNewObject(){ return new GameObject(); } 
    }; 
    public static GameObject allocate() { return pool.obtain(); } 
    private GameObject(){} 
    public void free() { pool.free(this); } 
} 

GameObject的構造是不可訪問愉快地向任何人。

+0

我不能讓它成爲一個內部類,因爲這個池是一個靜態成員,並且不包含在一個實例中。 – terryhau

+0

+1:你應該能夠使它成爲一個嵌套類(或靜態內部類),它應該可以正常工作。 –

+0

@Femi看起來是一個很好的解決方案。謝謝。 – terryhau

2

作爲最後的手段,您可以使用反射。對於其他選擇,其他人已經告訴。我記得Spring容器能夠初始化具有私有構造函數的類。我對此感到驚訝。我想它也使用這個技巧。好處可能是更通用。

public static void main(String... args) { 
    try { 
     Constructor c = GameObject.class.getDeclaredConstructor(); 
     c.setAccessible(true); // solution 
     c.newInstance(); 

     // production code should handle these exceptions more gracefully 
    } catch (InvocationTargetException x) { 
     x.printStackTrace(); 
    } catch (NoSuchMethodException x) { 
     x.printStackTrace(); 
    } catch (InstantiationException x) { 
     x.printStackTrace(); 
    } catch (IllegalAccessException x) { 
     x.printStackTrace(); 
    } 
    } 
+0

謝謝。我設法讓它與這種方法一起工作。 – terryhau

+0

接受我的答案,如果真的有幫助。 :-) –

+0

非常感謝:D這真的幫了我很大的忙。但順便說一下:什麼聲明我的代碼是否有權限設置構造函數可訪問? – MinecraftShamrock

1

改變:不要試圖讓你的代碼跳過循環。使用靜態分析來執行這樣的規則。如果你不小心做了一些你不想做的事情,這些工具就會抓住它。