Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: Only allow instantiation by one class

I want certain classes in my project to be pooled. And so I don't want to be able to instantiate these classes using: new SomeClass(), but instead obtain a new item from the pool using SomeClass.allocate(). I have this kind of code for each class that needs pooling.

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); }
    ...
}

Now I can disable the normal way of instantiating by making the default constructor private, but the problem is that the pool needs to instantiate the class when it's created, and also when the pool needs to expand.

Is there some way to limit construction to only by the pool?

like image 428
terryhau Avatar asked Aug 20 '11 05:08

terryhau


1 Answers

You have 2 options I can see: either make it an inner-class of the pool or make the allocate method package-private and put it in the same package as the pool.

EDIT: Ah. Just make the constructor private and then override whatever method the Pool uses to create new instances. As a (crude) example using your frame above:

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

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

    public void free(T obj) {}
}

and

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's constructor is happily inaccessible to anyone else.

like image 55
Femi Avatar answered Sep 22 '22 21:09

Femi