Create a singleton object using Class.forName ()?

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

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

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

Thanks,

+5
source share
5 answers

getInstance() - newInstance(). , , ...

setAccessible() , .

-, ( ).

+8

, factory , . factory

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

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:
   }
}

. Singleton .

+7

, . , , "instance()", -

Class c = Class.forName("MySingleton");
Method m = c.getDeclaredMethod("instance",null);
MySingleton singleton = m.invoke(null,null);
+2

HashMap . , - (Guice?)

, :

package tests;
public class EnumSingleton {
    public static void main(String[] args) throws Exception {
        Class<?> c = Class.forName("tests.Singleton1");
        Operation instance = Operation.class.cast(c.getEnumConstants()[0]);
        System.out.println(instance.getTHEAnswer());

        c = Class.forName("tests.Singleton2");
        instance = Operation.class.cast(c.getEnumConstants()[0]);
        System.out.println(instance.getTHEAnswer());
    }
}
interface Operation {
    int getTHEAnswer();
}
enum Singleton1 implements Operation {
    INSTANCE;
    @Override
    public int getTHEAnswer() {
        return 42;
    }
}
enum Singleton2 implements Operation {
    INSTANCE;
    @Override
    public int getTHEAnswer() {
        return 84;
    }
}

. .

+1

factory? - , .

Bottom line: if a class should be known as a singleton, then it should be responsible for this police activity. Therefore, it should correspond to some implementation of the template, and if you want a dynamic choice among such classes, then you need to be able to predict the "Factory" approach.

0
source

All Articles