Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Instantiate singleton object using Class.forName()?

I want to instantiate one instance of a class from the string name of the class. ( using Class.forName().newInstance(). )

Here's the problem: I want that instance to be a singleton.. I could do this using a singleton pattern, except that newInstance calls the default constructor for a class, and with a singleton, that constructor must be "private"..

Is there a solution? I could think of a less elegant way to do this (using a hashmap as a lookup table..), but would prefer a better solution..

Thanks,

like image 418
javaphild Avatar asked Jul 14 '09 20:07

javaphild


2 Answers

A classic singleton also has a static getInstance() method - call that via reflection instead of using newInstance(). Yeah, it's more work, but that's how it is...

Or you could use setAccessible() to call the private constructor anyway, but you'd break the singleton and go to hell.

Thirdly, you could avoid having a Singleton altogether and find a better soltion (there usually is).

like image 108
Michael Borgwardt Avatar answered Oct 10 '22 01:10

Michael Borgwardt


You could use reflection to get a reference to a static factory method of the class, and then invoke that. The factory method could enforce the singleton pattern

Class c = Class.forName("test.MyClass");
Method factoryMethod = c.getDeclaredMethod("getInstance");
Object singleton = factoryMethod.invoke(null, null);

And then

public class MyClass {

   private static MyClass instance;

   private MyClass() { 
      // private c'tor 
   }

   public static synchronized MyClass getInstance() {
      if (instance == null) {
         instance = new MyClass();
      }
      return instance:
   }
}

Warning: Singleton design pattern may be detrimental to your longterm health.

like image 32
skaffman Avatar answered Oct 10 '22 03:10

skaffman