Java: allow instance creation by only one class

I want certain classes in my project to be combined. And so I don’t want to instantiate these classes using: new SomeClass (), but instead I get a new element from the pool using SomeClass.allocate (). I have code for each class that needs to be merged.

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 turn off the usual way of instantiating, making the default constructor private, but the problem is that the pool must instantiate the class when it is created, and also when the pool needs to expand.

Is there a way to limit the build to only the pool?

+4
source share
3 answers

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

EDIT: Ah. Just make the constructor private, and then override any method that Pool uses to create new instances. As a (rough) 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); } } 
Constructor

GameObject happily inaccessible to anyone else.

+2
source

As a last resort, you can use reflection. For other options, other people are already telling. I remember that a Spring container is able to initialize a class with its own constructor. And I am surprised by this. I think he also uses this trick. The advantage may be more general.

 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(); } } 
+2
source

Volatility: Do not try to translate code through hoops. Use static analysis to apply such rules. Tools will catch him if you accidentally do something that you did not intend to.

+1
source

All Articles